@mui/x-virtualizer 1.0.0-beta.1 → 9.0.0-alpha.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.
- package/CHANGELOG.md +267 -1
- package/features/dimensions.d.mts +1 -0
- package/features/dimensions.d.ts +1 -0
- package/features/dimensions.js +2 -1
- package/features/dimensions.mjs +2 -1
- package/features/virtualization/layout.d.mts +32 -0
- package/features/virtualization/layout.d.ts +32 -0
- package/features/virtualization/layout.js +77 -19
- package/features/virtualization/layout.mjs +83 -25
- package/features/virtualization/virtualization.d.mts +18 -1
- package/features/virtualization/virtualization.d.ts +18 -1
- package/features/virtualization/virtualization.js +22 -7
- package/features/virtualization/virtualization.mjs +22 -7
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,271 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.0.0
|
|
4
|
+
|
|
5
|
+
<!-- generated comparing v9.0.0-rc.0..master -->
|
|
6
|
+
|
|
7
|
+
_Apr 8, 2026_
|
|
8
|
+
|
|
9
|
+
🥳 We're excited to announce the stable release of MUI X v9!
|
|
10
|
+
This major release includes many new features and improvements. Here are some highlights ✨:
|
|
11
|
+
|
|
12
|
+
- Data Grid – [Charts integration](https://mui.com/x/react-data-grid/charts-integration/) [Premium]
|
|
13
|
+
- Data Grid – [AI Assistant](https://mui.com/x/react-data-grid/ai-assistant/) [Premium]
|
|
14
|
+
- Data Grid – [Undo and redo](https://mui.com/x/react-data-grid/undo-redo/) [Premium]
|
|
15
|
+
- Data Grid – [Drag fill](https://mui.com/x/react-data-grid/clipboard/#drag-to-fill) [Premium]
|
|
16
|
+
- Data Grid – [longText column type](https://mui.com/x/react-data-grid/column-definition/#column-types)
|
|
17
|
+
- Charts – [Interaction and accessibility](https://mui.com/x/react-charts/accessibility/)
|
|
18
|
+
- Charts – [Candlestick](https://mui.com/x/react-charts/candlestick/) [Premium]
|
|
19
|
+
- Charts – [Range bar charts](https://mui.com/x/react-charts/range-bar/) [Premium]
|
|
20
|
+
- Charts – [WebGL Heatmap renderer](https://mui.com/x/react-charts/heatmap/#webgl-renderer) [Premium]
|
|
21
|
+
- Tree View – [Virtualization](https://mui.com/x/react-tree-view/rich-tree-view/virtualization/) [Pro]
|
|
22
|
+
- New [Scheduler](https://mui.com/x/react-scheduler/) packages [Alpha]
|
|
23
|
+
|
|
24
|
+
We'd like to extend a big thank you to the 5 contributors who made this release possible.
|
|
25
|
+
The following team members contributed to this release:
|
|
26
|
+
@DanailH, @LukasTy, @MBilalShafi, @oliviertassinari, @siriwatknp
|
|
27
|
+
|
|
28
|
+
### Data Grid
|
|
29
|
+
|
|
30
|
+
#### `@mui/x-data-grid@9.0.0`
|
|
31
|
+
|
|
32
|
+
Internal changes.
|
|
33
|
+
|
|
34
|
+
#### `@mui/x-data-grid-pro@9.0.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
35
|
+
|
|
36
|
+
Same changes as in `@mui/x-data-grid@9.0.0`, plus:
|
|
37
|
+
|
|
38
|
+
- [DataGridPro] Preserve parent selection for non-selectable children (#21132) @MBilalShafi
|
|
39
|
+
|
|
40
|
+
#### `@mui/x-data-grid-premium@9.0.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
41
|
+
|
|
42
|
+
Same changes as in `@mui/x-data-grid-pro@9.0.0`, plus:
|
|
43
|
+
|
|
44
|
+
- [DataGridPremium] Drag fill (#21717) @MBilalShafi
|
|
45
|
+
|
|
46
|
+
### Date and Time Pickers
|
|
47
|
+
|
|
48
|
+
#### Breaking changes
|
|
49
|
+
|
|
50
|
+
- Removed the legacy Pickers and Field TextField props (for example: `InputProps`) in favor of the nested `slotProps`. [Read more](https://mui.com/x/migration/migration-pickers-v8/#drop-deprecated-pickerstextfield-props)
|
|
51
|
+
- The `utils` field in `PickersAdapterContextValue` has been removed in favor of the `adapter` field.
|
|
52
|
+
This should no longer affect you, as the context export has also been removed.
|
|
53
|
+
- `MuiPickersAdapterContext` export has been removed.
|
|
54
|
+
Prefer using the `usePickerAdapter` hook. [Read more](https://mui.com/x/migration/migration-pickers-v8/#localizationprovider-breaking-changes).
|
|
55
|
+
|
|
56
|
+
#### `@mui/x-date-pickers@9.0.0`
|
|
57
|
+
|
|
58
|
+
- [pickers] Refactor `PickersTextField` to use `slotProps` approach (#22002) @LukasTy
|
|
59
|
+
- [pickers] Remove deprecated LocalizationProvider legacy API (#22010) @LukasTy
|
|
60
|
+
|
|
61
|
+
#### `@mui/x-date-pickers-pro@9.0.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
62
|
+
|
|
63
|
+
Same changes as in `@mui/x-date-pickers@9.0.0`.
|
|
64
|
+
|
|
65
|
+
### Charts
|
|
66
|
+
|
|
67
|
+
#### `@mui/x-charts@9.0.0`
|
|
68
|
+
|
|
69
|
+
Internal changes.
|
|
70
|
+
|
|
71
|
+
#### `@mui/x-charts-pro@9.0.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
72
|
+
|
|
73
|
+
Same changes as in `@mui/x-charts@9.0.0`.
|
|
74
|
+
|
|
75
|
+
#### `@mui/x-charts-premium@9.0.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
76
|
+
|
|
77
|
+
Same changes as in `@mui/x-charts-pro@9.0.0`.
|
|
78
|
+
|
|
79
|
+
### Tree View
|
|
80
|
+
|
|
81
|
+
#### `@mui/x-tree-view@9.0.0`
|
|
82
|
+
|
|
83
|
+
Internal changes.
|
|
84
|
+
|
|
85
|
+
#### `@mui/x-tree-view-pro@9.0.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
86
|
+
|
|
87
|
+
Same changes as in `@mui/x-tree-view@9.0.0`.
|
|
88
|
+
|
|
89
|
+
### Scheduler
|
|
90
|
+
|
|
91
|
+
#### `@mui/x-scheduler@9.0.0-alpha.0`
|
|
92
|
+
|
|
93
|
+
Internal changes.
|
|
94
|
+
|
|
95
|
+
#### `@mui/x-scheduler-premium@9.0.0-alpha.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
96
|
+
|
|
97
|
+
Same changes as in `@mui/x-scheduler-pro@9.0.0-alpha.0`.
|
|
98
|
+
|
|
99
|
+
### Codemod
|
|
100
|
+
|
|
101
|
+
#### `@mui/x-codemod@9.0.0`
|
|
102
|
+
|
|
103
|
+
Internal changes.
|
|
104
|
+
|
|
105
|
+
### Docs
|
|
106
|
+
|
|
107
|
+
- [docs] Add explanation for v8 -> v9 license migration (#22004) @DanailH
|
|
108
|
+
|
|
109
|
+
### Core
|
|
110
|
+
|
|
111
|
+
- [code-infra] Optimize dependency definition (#22006) @LukasTy
|
|
112
|
+
- [internal] Prepare v9 stable (#22018) @siriwatknp
|
|
113
|
+
- [internal] Remove 'conf' from codebase (#21989) @oliviertassinari
|
|
114
|
+
|
|
115
|
+
## 9.0.0-rc.0
|
|
116
|
+
|
|
117
|
+
<!-- generated comparing v9.0.0-beta.0..master -->
|
|
118
|
+
|
|
119
|
+
_Apr 7, 2026_
|
|
120
|
+
|
|
121
|
+
We'd like to extend a big thank you to the 18 contributors who made this release possible.
|
|
122
|
+
|
|
123
|
+
Special thanks go out to these community members for their valuable contributions:
|
|
124
|
+
@mixelburg, @sibananda485, @youjin-hong
|
|
125
|
+
|
|
126
|
+
The following team members contributed to this release:
|
|
127
|
+
@aemartos, @alexfauquette, @arminmeh, @brijeshb42, @flaviendelangle, @JCQuintas, @LukasTy, @mapache-salvaje, @MBilalShafi, @michelengelen, @noraleonte, @rita-codes, @romgrk, @siriwatknp, @ZeeshanTamboli
|
|
128
|
+
|
|
129
|
+
### Data Grid
|
|
130
|
+
|
|
131
|
+
#### `@mui/x-data-grid@9.0.0-rc.0`
|
|
132
|
+
|
|
133
|
+
- [DataGrid] Rename filter panel `Columns` label to singular `Column` (#21935) @youjin-hong
|
|
134
|
+
- [DataGrid] Export `GridColumnUnsortedIconProps` for custom column icon slots (#21658) @mixelburg
|
|
135
|
+
- [DataGrid] Remove `x-virtualizer`'s `virtualScroller` from public API (#21936) @romgrk
|
|
136
|
+
- [DataGrid][virtualizer] Scrolling without render gaps (#21616) @romgrk
|
|
137
|
+
|
|
138
|
+
#### `@mui/x-data-grid-pro@9.0.0-rc.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
139
|
+
|
|
140
|
+
Same changes as in `@mui/x-data-grid@9.0.0-rc.0`, plus:
|
|
141
|
+
|
|
142
|
+
- [DataGridPro] Improve trigger for nested row reordering (#21642) @MBilalShafi
|
|
143
|
+
- [DataGridPro] Undeprecate `onRowsScrollEnd` prop (#21912) @MBilalShafi
|
|
144
|
+
|
|
145
|
+
#### `@mui/x-data-grid-premium@9.0.0-rc.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
146
|
+
|
|
147
|
+
Same changes as in `@mui/x-data-grid-pro@9.0.0-rc.0`, plus:
|
|
148
|
+
|
|
149
|
+
- [DataGridPremium] Fix clipboard paste issue in portal (#21931) @sibananda485
|
|
150
|
+
|
|
151
|
+
### Date and Time Pickers
|
|
152
|
+
|
|
153
|
+
#### Breaking changes
|
|
154
|
+
|
|
155
|
+
- Accessible DOM structure is now the only default. [Read more](https://mui.com/x/migration/migration-pickers-v8/#accessible-dom-structure-is-now-the-default)
|
|
156
|
+
- The `PickerDay2` and `DateRangePickerDay2` components were propagated to stable while removing the previous defaults. [Read more](https://mui.com/x/migration/migration-pickers-v8/#day-slot)
|
|
157
|
+
|
|
158
|
+
#### `@mui/x-date-pickers@9.0.0-rc.0`
|
|
159
|
+
|
|
160
|
+
- [pickers] Remove `PickersDay` and `DateRangePickerDay` and promote their `2` versions as replacements (#21739) @michelengelen
|
|
161
|
+
|
|
162
|
+
#### `@mui/x-date-pickers-pro@9.0.0-rc.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
163
|
+
|
|
164
|
+
Same changes as in `@mui/x-date-pickers@9.0.0-rc.0`.
|
|
165
|
+
|
|
166
|
+
### Charts
|
|
167
|
+
|
|
168
|
+
#### `@mui/x-charts@9.0.0-rc.0.0`
|
|
169
|
+
|
|
170
|
+
- [charts] Make line visibility toggle start from the baseline (#21893) @alexfauquette
|
|
171
|
+
- [charts] Remove the container overflow (#21955) @alexfauquette
|
|
172
|
+
- [charts] Revert `theme.alpha` for non-channel token (#21965) @siriwatknp
|
|
173
|
+
|
|
174
|
+
#### `@mui/x-charts-pro@9.0.0-rc.0.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
175
|
+
|
|
176
|
+
Same changes as in `@mui/x-charts@9.0.0-rc.0.0`, plus:
|
|
177
|
+
|
|
178
|
+
- [charts-pro] Zoom slider touch improvements (#21832) @JCQuintas
|
|
179
|
+
- [charts-pro] Add `seriesIds` filter to zoom slider preview (#21933) @JCQuintas
|
|
180
|
+
- [charts-pro] Fix zoom slider preview with discard filter mode (#21883) @JCQuintas
|
|
181
|
+
|
|
182
|
+
#### `@mui/x-charts-premium@9.0.0-rc.0.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
183
|
+
|
|
184
|
+
Same changes as in `@mui/x-charts-pro@9.0.0-rc.0.0`, plus:
|
|
185
|
+
|
|
186
|
+
- [charts-premium] Add series `valueFormatter` to candlestick chart (#21905) @JCQuintas
|
|
187
|
+
- [charts-premium] Add zoom slider preview support for candlestick charts (#21914) @JCQuintas
|
|
188
|
+
- [charts-premium] Allow color customization in `Candlestick` chart (#21838) @JCQuintas
|
|
189
|
+
- [charts-premium] Support hide/show for OHLC (candlestick) series (#21807) @Copilot
|
|
190
|
+
- [charts-premium] Add `dataset` support to `Candlestick` chart (#21872) @JCQuintas
|
|
191
|
+
- [charts-premium] Add candlestick page to sidebar navigation (#21834) @JCQuintas
|
|
192
|
+
|
|
193
|
+
### Tree View
|
|
194
|
+
|
|
195
|
+
#### `@mui/x-tree-view@9.0.0-rc.0`
|
|
196
|
+
|
|
197
|
+
Internal changes.
|
|
198
|
+
|
|
199
|
+
#### `@mui/x-tree-view-pro@9.0.0-rc.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
200
|
+
|
|
201
|
+
Same changes as in `@mui/x-tree-view@9.0.0-rc.0`, plus:
|
|
202
|
+
|
|
203
|
+
- [RichTreeViewPro] Allow to auto-expand lazy loaded items (#21759) @flaviendelangle
|
|
204
|
+
|
|
205
|
+
### Scheduler
|
|
206
|
+
|
|
207
|
+
#### `@mui/x-scheduler@9.0.0-alpha.0`
|
|
208
|
+
|
|
209
|
+
- [scheduler] Add locale files, adapt l10n scripts, and add localization table to docs (#21870) @rita-codes
|
|
210
|
+
- [scheduler] Add planned features to the docs (#21705) @rita-codes
|
|
211
|
+
- [scheduler] Add scheduler to docs introduction (#21845) @rita-codes
|
|
212
|
+
- [scheduler] Add wide docs to scheduler (#21860) @noraleonte
|
|
213
|
+
- [scheduler] All day event bugfixes (#21884) @noraleonte
|
|
214
|
+
- [scheduler] Autofocus title field (#21947) @noraleonte
|
|
215
|
+
- [scheduler] Change default event creation trigger to single click (#21979) @rita-codes
|
|
216
|
+
- [scheduler] Change order of the views on the view selector (#21904) @rita-codes
|
|
217
|
+
- [scheduler] Disabled border color for the repeat day picker in dark mode (#21987) @rita-codes
|
|
218
|
+
- [scheduler] Drop unused dependency (#21956) @flaviendelangle
|
|
219
|
+
- [scheduler] Fix all-day event shifting to previous day in negative UTC offsets (#21994) @rita-codes
|
|
220
|
+
- [scheduler] Fix dark theme localization demos (#21992) @noraleonte
|
|
221
|
+
- [scheduler] Fix licensing confusion in docs (#21939) @rita-codes
|
|
222
|
+
- [scheduler] Fix preferences menu width shift when toggling options + Improve preferences menu accessibility (#21902) @rita-codes
|
|
223
|
+
- [scheduler] Prepare for the alpha launch (#21859) @rita-codes
|
|
224
|
+
- [scheduler] Sync Base UI internals and apply good practices (#21946) @flaviendelangle
|
|
225
|
+
- [scheduler] Update close modal aria label translation (#21940) @rita-codes
|
|
226
|
+
- [scheduler] Add Spanish (es-ES) locale (#21900) @rita-codes
|
|
227
|
+
- [scheduler] Improve French (fr-FR) locale (#21941) @rita-codes
|
|
228
|
+
- [scheduler] Improve Romanian (ro-RO) locale (#21942) @rita-codes
|
|
229
|
+
|
|
230
|
+
#### `@mui/x-scheduler-premium@9.0.0-alpha.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
231
|
+
|
|
232
|
+
Same changes as in `@mui/x-scheduler@9.0.0-alpha.0`.
|
|
233
|
+
|
|
234
|
+
### Codemod
|
|
235
|
+
|
|
236
|
+
#### `@mui/x-codemod@9.0.0-rc.0`
|
|
237
|
+
|
|
238
|
+
Internal changes.
|
|
239
|
+
|
|
240
|
+
### Docs
|
|
241
|
+
|
|
242
|
+
- [docs] Fix JSDOM → jsdom casing (#21907) @JCQuintas
|
|
243
|
+
- [docs] Remove Joy UI references and dependency (#21937) @siriwatknp
|
|
244
|
+
- [docs] Remove none generated files (#21886) @alexfauquette
|
|
245
|
+
- [docs] Remove unused interactive demo code (#21945) @LukasTy
|
|
246
|
+
- [docs] Revise the Funnel doc (#21677) @mapache-salvaje
|
|
247
|
+
- [docs] Revise the Line chart docs (#21554) @mapache-salvaje
|
|
248
|
+
- [docs] Revise the Radar doc (#21674) @mapache-salvaje
|
|
249
|
+
- [docs] Revise the Sankey doc (#21678) @mapache-salvaje
|
|
250
|
+
- [docs] Revise the Scatter chart docs (#21564) @mapache-salvaje
|
|
251
|
+
|
|
252
|
+
### Core
|
|
253
|
+
|
|
254
|
+
- [docs-infra] Update to the latest monorepo (#21971) @brijeshb42
|
|
255
|
+
- [internal] Remove checks for `materialVersion >= 6` (#21975) @LukasTy
|
|
256
|
+
|
|
257
|
+
### Miscellaneous
|
|
258
|
+
|
|
259
|
+
- [core] Bump @mui/material to v9.0.0-beta.1 (#21858) @siriwatknp
|
|
260
|
+
- [core] Update browserslistrc (#21974) @siriwatknp
|
|
261
|
+
- [deps] Bump minimum core packages to 7.3.0 to adopt theme color manipulator (#21892) @siriwatknp
|
|
262
|
+
- [telemetry] Prefer upstream remote over origin for `projectId` (#21882) @aemartos
|
|
263
|
+
- [telemetry] Send `repoHash`, `[x]packageNameHash`, and `rootPathHash` alongside `projectId` (#21896) @aemartos
|
|
264
|
+
- [test] Exclude flaky `DataGrid` argos test (#21977) @MBilalShafi
|
|
265
|
+
- [test] Fix flaky `DataGrid` test (#22000) @arminmeh
|
|
266
|
+
- [test] Remove `componentsProp` test from `describeConformance` (#21897) @ZeeshanTamboli
|
|
267
|
+
- [x-license] Change `orderId` type from `number` to `string` (#21885) @aemartos
|
|
268
|
+
|
|
3
269
|
## 9.0.0-beta.0
|
|
4
270
|
|
|
5
271
|
<!-- generated comparing v9.0.0-alpha.4..master -->
|
|
@@ -313,7 +579,7 @@ Same changes as in `@mui/x-charts-pro@9.0.0-alpha.3`, plus:
|
|
|
313
579
|
- Remove deprecated CSS state classes from `treeItemClasses`: `expanded`, `selected`, `focused`, `disabled`, `editable`, `editing` (use `[data-expanded]`, `[data-selected]`, etc.)
|
|
314
580
|
- The `<RichTreeViewPro />` component has now virtualization enabled by default.
|
|
315
581
|
- The items used inside the `<RichTreeViewPro />` now have a default height of `32px`.
|
|
316
|
-
- The
|
|
582
|
+
- The items of the `<RichTreeViewPro />` are now rendered as a flat list instead of a nested tree.
|
|
317
583
|
|
|
318
584
|
#### `@mui/x-tree-view@9.0.0-alpha.3`
|
|
319
585
|
|
|
@@ -27,6 +27,7 @@ export declare const Dimensions: {
|
|
|
27
27
|
rowPositions: (state: BaseState) => number[];
|
|
28
28
|
columnPositions: (_: any, columns: ColumnWithWidth[]) => number[];
|
|
29
29
|
needsHorizontalScrollbar: (state: BaseState) => boolean;
|
|
30
|
+
needsVerticalScrollbar: (state: BaseState) => boolean;
|
|
30
31
|
};
|
|
31
32
|
};
|
|
32
33
|
export declare namespace Dimensions {
|
package/features/dimensions.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare const Dimensions: {
|
|
|
27
27
|
rowPositions: (state: BaseState) => number[];
|
|
28
28
|
columnPositions: (_: any, columns: ColumnWithWidth[]) => number[];
|
|
29
29
|
needsHorizontalScrollbar: (state: BaseState) => boolean;
|
|
30
|
+
needsVerticalScrollbar: (state: BaseState) => boolean;
|
|
30
31
|
};
|
|
31
32
|
};
|
|
32
33
|
export declare namespace Dimensions {
|
package/features/dimensions.js
CHANGED
|
@@ -61,7 +61,8 @@ const selectors = {
|
|
|
61
61
|
}
|
|
62
62
|
return positions;
|
|
63
63
|
}),
|
|
64
|
-
needsHorizontalScrollbar: state => state.dimensions.
|
|
64
|
+
needsHorizontalScrollbar: state => state.dimensions.viewportInnerSize.width > 0 && state.dimensions.columnsTotalWidth > state.dimensions.viewportInnerSize.width,
|
|
65
|
+
needsVerticalScrollbar: state => state.dimensions.viewportInnerSize.height > 0 && state.dimensions.contentSize.height > state.dimensions.viewportInnerSize.height
|
|
65
66
|
};
|
|
66
67
|
const Dimensions = exports.Dimensions = {
|
|
67
68
|
initialize: initializeState,
|
package/features/dimensions.mjs
CHANGED
|
@@ -54,7 +54,8 @@ const selectors = {
|
|
|
54
54
|
}
|
|
55
55
|
return positions;
|
|
56
56
|
}),
|
|
57
|
-
needsHorizontalScrollbar: state => state.dimensions.
|
|
57
|
+
needsHorizontalScrollbar: state => state.dimensions.viewportInnerSize.width > 0 && state.dimensions.columnsTotalWidth > state.dimensions.viewportInnerSize.width,
|
|
58
|
+
needsVerticalScrollbar: state => state.dimensions.viewportInnerSize.height > 0 && state.dimensions.contentSize.height > state.dimensions.viewportInnerSize.height
|
|
58
59
|
};
|
|
59
60
|
export const Dimensions = {
|
|
60
61
|
initialize: initializeState,
|
|
@@ -36,6 +36,17 @@ export declare class LayoutDataGrid extends Layout<DataGridElements> {
|
|
|
36
36
|
role: string;
|
|
37
37
|
tabIndex: number | undefined;
|
|
38
38
|
};
|
|
39
|
+
scrollerContentProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
40
|
+
style: React.CSSProperties | undefined;
|
|
41
|
+
role: string;
|
|
42
|
+
};
|
|
43
|
+
viewportProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
44
|
+
style: {
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
};
|
|
48
|
+
role: string;
|
|
49
|
+
};
|
|
39
50
|
contentProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
40
51
|
style: React.CSSProperties;
|
|
41
52
|
role: string;
|
|
@@ -45,6 +56,11 @@ export declare class LayoutDataGrid extends Layout<DataGridElements> {
|
|
|
45
56
|
transform: string;
|
|
46
57
|
};
|
|
47
58
|
};
|
|
59
|
+
containerVerticalProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
60
|
+
style: {
|
|
61
|
+
transform: string;
|
|
62
|
+
};
|
|
63
|
+
} | undefined;
|
|
48
64
|
scrollbarHorizontalProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
49
65
|
ref: any;
|
|
50
66
|
scrollPosition: {
|
|
@@ -78,6 +94,17 @@ export declare class LayoutDataGridLegacy extends LayoutDataGrid {
|
|
|
78
94
|
role: string;
|
|
79
95
|
tabIndex: number | undefined;
|
|
80
96
|
};
|
|
97
|
+
getScrollerContentProps: () => {
|
|
98
|
+
style: React.CSSProperties | undefined;
|
|
99
|
+
role: string;
|
|
100
|
+
};
|
|
101
|
+
getViewportProps: () => {
|
|
102
|
+
style: {
|
|
103
|
+
width: number;
|
|
104
|
+
height: number;
|
|
105
|
+
};
|
|
106
|
+
role: string;
|
|
107
|
+
};
|
|
81
108
|
getContentProps: () => {
|
|
82
109
|
style: React.CSSProperties;
|
|
83
110
|
role: string;
|
|
@@ -104,6 +131,11 @@ export declare class LayoutDataGridLegacy extends LayoutDataGrid {
|
|
|
104
131
|
current: import("../../models/index.mjs").ScrollPosition;
|
|
105
132
|
};
|
|
106
133
|
};
|
|
134
|
+
getContainerVerticalProps: () => {
|
|
135
|
+
style: {
|
|
136
|
+
transform: string;
|
|
137
|
+
};
|
|
138
|
+
} | undefined;
|
|
107
139
|
};
|
|
108
140
|
}
|
|
109
141
|
type ListElements = BaseElements;
|
|
@@ -36,6 +36,17 @@ export declare class LayoutDataGrid extends Layout<DataGridElements> {
|
|
|
36
36
|
role: string;
|
|
37
37
|
tabIndex: number | undefined;
|
|
38
38
|
};
|
|
39
|
+
scrollerContentProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
40
|
+
style: React.CSSProperties | undefined;
|
|
41
|
+
role: string;
|
|
42
|
+
};
|
|
43
|
+
viewportProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
44
|
+
style: {
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
};
|
|
48
|
+
role: string;
|
|
49
|
+
};
|
|
39
50
|
contentProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
40
51
|
style: React.CSSProperties;
|
|
41
52
|
role: string;
|
|
@@ -45,6 +56,11 @@ export declare class LayoutDataGrid extends Layout<DataGridElements> {
|
|
|
45
56
|
transform: string;
|
|
46
57
|
};
|
|
47
58
|
};
|
|
59
|
+
containerVerticalProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
60
|
+
style: {
|
|
61
|
+
transform: string;
|
|
62
|
+
};
|
|
63
|
+
} | undefined;
|
|
48
64
|
scrollbarHorizontalProps: (args_0: Virtualization.State<Layout<AnyElements>> & Dimensions.State) => {
|
|
49
65
|
ref: any;
|
|
50
66
|
scrollPosition: {
|
|
@@ -78,6 +94,17 @@ export declare class LayoutDataGridLegacy extends LayoutDataGrid {
|
|
|
78
94
|
role: string;
|
|
79
95
|
tabIndex: number | undefined;
|
|
80
96
|
};
|
|
97
|
+
getScrollerContentProps: () => {
|
|
98
|
+
style: React.CSSProperties | undefined;
|
|
99
|
+
role: string;
|
|
100
|
+
};
|
|
101
|
+
getViewportProps: () => {
|
|
102
|
+
style: {
|
|
103
|
+
width: number;
|
|
104
|
+
height: number;
|
|
105
|
+
};
|
|
106
|
+
role: string;
|
|
107
|
+
};
|
|
81
108
|
getContentProps: () => {
|
|
82
109
|
style: React.CSSProperties;
|
|
83
110
|
role: string;
|
|
@@ -104,6 +131,11 @@ export declare class LayoutDataGridLegacy extends LayoutDataGrid {
|
|
|
104
131
|
current: import("../../models/index.js").ScrollPosition;
|
|
105
132
|
};
|
|
106
133
|
};
|
|
134
|
+
getContainerVerticalProps: () => {
|
|
135
|
+
style: {
|
|
136
|
+
transform: string;
|
|
137
|
+
};
|
|
138
|
+
} | undefined;
|
|
107
139
|
};
|
|
108
140
|
}
|
|
109
141
|
type ListElements = BaseElements;
|
|
@@ -64,19 +64,58 @@ class LayoutDataGrid extends Layout {
|
|
|
64
64
|
// https://github.com/mui/mui-x/pull/13891#discussion_r1683416024
|
|
65
65
|
tabIndex: platform.isFirefox ? -1 : undefined
|
|
66
66
|
})),
|
|
67
|
+
scrollerContentProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.layoutMode, _dimensions.Dimensions.selectors.dimensions, _dimensions.Dimensions.selectors.needsVerticalScrollbar, _dimensions.Dimensions.selectors.needsHorizontalScrollbar, (layoutMode, dimensions, needsVerticalScrollbar, needsHorizontalScrollbar) => {
|
|
68
|
+
let style;
|
|
69
|
+
if (layoutMode === 'controlled') {
|
|
70
|
+
const {
|
|
71
|
+
contentSize,
|
|
72
|
+
scrollbarSize,
|
|
73
|
+
topContainerHeight,
|
|
74
|
+
bottomContainerHeight,
|
|
75
|
+
minimalContentHeight,
|
|
76
|
+
columnsTotalWidth
|
|
77
|
+
} = dimensions;
|
|
78
|
+
const verticalScrollbarSize = needsVerticalScrollbar ? scrollbarSize : 0;
|
|
79
|
+
const horizontalScrollbarSize = needsHorizontalScrollbar ? scrollbarSize : 0;
|
|
80
|
+
const contentHeight = contentSize.height === 0 ? minimalContentHeight : contentSize.height;
|
|
81
|
+
const width = needsHorizontalScrollbar ? verticalScrollbarSize + columnsTotalWidth : 'auto';
|
|
82
|
+
const height = cssAdd(cssAdd(cssAdd(contentHeight, topContainerHeight), bottomContainerHeight), horizontalScrollbarSize);
|
|
83
|
+
style = {
|
|
84
|
+
width,
|
|
85
|
+
height,
|
|
86
|
+
flex: '0 0 auto'
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
style,
|
|
91
|
+
role: 'presentation'
|
|
92
|
+
};
|
|
93
|
+
}),
|
|
94
|
+
viewportProps: (0, _store.createSelectorMemoized)(_dimensions.Dimensions.selectors.dimensions, dimensions => ({
|
|
95
|
+
style: {
|
|
96
|
+
width: dimensions.viewportOuterSize.width,
|
|
97
|
+
height: dimensions.viewportOuterSize.height
|
|
98
|
+
},
|
|
99
|
+
role: 'presentation'
|
|
100
|
+
})),
|
|
67
101
|
contentProps: (0, _store.createSelectorMemoized)(_dimensions.Dimensions.selectors.contentHeight, _dimensions.Dimensions.selectors.minimalContentHeight, _dimensions.Dimensions.selectors.columnsTotalWidth, _dimensions.Dimensions.selectors.needsHorizontalScrollbar, (contentHeight, minimalContentHeight, columnsTotalWidth, needsHorizontalScrollbar) => ({
|
|
68
102
|
style: {
|
|
69
103
|
width: needsHorizontalScrollbar ? columnsTotalWidth : 'auto',
|
|
70
|
-
|
|
71
|
-
|
|
104
|
+
height: contentHeight === 0 ? minimalContentHeight : contentHeight,
|
|
105
|
+
flex: '0 0 auto'
|
|
72
106
|
},
|
|
73
107
|
role: 'presentation'
|
|
74
108
|
})),
|
|
75
|
-
positionerProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.offsetTop, offsetTop => ({
|
|
109
|
+
positionerProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.layoutMode, _virtualization.Virtualization.selectors.offsetTop, _virtualization.Virtualization.selectors.scrollPosition, (layoutMode, offsetTop, scrollPosition) => ({
|
|
76
110
|
style: {
|
|
77
|
-
transform: `translate3d(0, ${offsetTop}px, 0)`
|
|
111
|
+
transform: layoutMode === 'uncontrolled' ? `translate3d(0, ${offsetTop}px, 0)` : `translate3d(${-scrollPosition.current.left}px, ${offsetTop - scrollPosition.current.top}px, 0)`
|
|
78
112
|
}
|
|
79
113
|
})),
|
|
114
|
+
containerVerticalProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.layoutMode, _virtualization.Virtualization.selectors.scrollPosition, (layoutMode, scrollPosition) => layoutMode === 'uncontrolled' ? undefined : {
|
|
115
|
+
style: {
|
|
116
|
+
transform: `translate3d(${-scrollPosition.current.left}px, 0, 0)`
|
|
117
|
+
}
|
|
118
|
+
}),
|
|
80
119
|
scrollbarHorizontalProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.context, _virtualization.Virtualization.selectors.scrollPosition, (context, scrollPosition) => ({
|
|
81
120
|
ref: context.scrollbarHorizontalRef,
|
|
82
121
|
scrollPosition
|
|
@@ -102,19 +141,25 @@ class LayoutDataGridLegacy extends LayoutDataGrid {
|
|
|
102
141
|
super.use(store, _params, _api, layoutParams);
|
|
103
142
|
const containerProps = store.use(LayoutDataGrid.selectors.containerProps);
|
|
104
143
|
const scrollerProps = store.use(LayoutDataGrid.selectors.scrollerProps);
|
|
144
|
+
const scrollerContentProps = store.use(LayoutDataGrid.selectors.scrollerContentProps);
|
|
145
|
+
const viewportProps = store.use(LayoutDataGrid.selectors.viewportProps);
|
|
105
146
|
const contentProps = store.use(LayoutDataGrid.selectors.contentProps);
|
|
106
147
|
const positionerProps = store.use(LayoutDataGrid.selectors.positionerProps);
|
|
107
148
|
const scrollbarVerticalProps = store.use(LayoutDataGrid.selectors.scrollbarVerticalProps);
|
|
108
149
|
const scrollbarHorizontalProps = store.use(LayoutDataGrid.selectors.scrollbarHorizontalProps);
|
|
109
150
|
const scrollAreaProps = store.use(LayoutDataGrid.selectors.scrollAreaProps);
|
|
151
|
+
const containerVerticalProps = store.use(LayoutDataGrid.selectors.containerVerticalProps);
|
|
110
152
|
return {
|
|
111
153
|
getContainerProps: () => containerProps,
|
|
112
154
|
getScrollerProps: () => scrollerProps,
|
|
155
|
+
getScrollerContentProps: () => scrollerContentProps,
|
|
156
|
+
getViewportProps: () => viewportProps,
|
|
113
157
|
getContentProps: () => contentProps,
|
|
114
158
|
getPositionerProps: () => positionerProps,
|
|
115
159
|
getScrollbarVerticalProps: () => scrollbarVerticalProps,
|
|
116
160
|
getScrollbarHorizontalProps: () => scrollbarHorizontalProps,
|
|
117
|
-
getScrollAreaProps: () => scrollAreaProps
|
|
161
|
+
getScrollAreaProps: () => scrollAreaProps,
|
|
162
|
+
getContainerVerticalProps: () => containerVerticalProps
|
|
118
163
|
};
|
|
119
164
|
}
|
|
120
165
|
}
|
|
@@ -144,20 +189,18 @@ class LayoutList extends Layout {
|
|
|
144
189
|
// https://github.com/mui/mui-x/pull/13891#discussion_r1683416024
|
|
145
190
|
tabIndex: platform.isFirefox ? -1 : undefined
|
|
146
191
|
})),
|
|
147
|
-
contentProps: (0, _store.createSelectorMemoized)(_dimensions.Dimensions.selectors.contentHeight, contentHeight => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
};
|
|
160
|
-
}),
|
|
192
|
+
contentProps: (0, _store.createSelectorMemoized)(_dimensions.Dimensions.selectors.contentHeight, contentHeight => ({
|
|
193
|
+
style: {
|
|
194
|
+
position: 'absolute',
|
|
195
|
+
display: 'inline-block',
|
|
196
|
+
width: '100%',
|
|
197
|
+
height: contentHeight,
|
|
198
|
+
top: 0,
|
|
199
|
+
left: 0,
|
|
200
|
+
zIndex: -1
|
|
201
|
+
},
|
|
202
|
+
role: 'presentation'
|
|
203
|
+
})),
|
|
161
204
|
positionerProps: (0, _store.createSelectorMemoized)(_virtualization.Virtualization.selectors.offsetTop, offsetTop => ({
|
|
162
205
|
style: {
|
|
163
206
|
height: offsetTop
|
|
@@ -216,4 +259,19 @@ function useScrollbarRefCallback(scrollerRef, refSetter, scrollProperty) {
|
|
|
216
259
|
scrollbar.removeEventListener('scroll', onScrollbarScroll);
|
|
217
260
|
};
|
|
218
261
|
});
|
|
262
|
+
}
|
|
263
|
+
function cssAdd(a, b) {
|
|
264
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
265
|
+
return a + b;
|
|
266
|
+
}
|
|
267
|
+
return `calc(${valueToCSSString(a)} + ${valueToCSSString(b)})`;
|
|
268
|
+
}
|
|
269
|
+
function valueToCSSString(value) {
|
|
270
|
+
if (typeof value === 'string') {
|
|
271
|
+
return value;
|
|
272
|
+
}
|
|
273
|
+
if (typeof value === 'undefined') {
|
|
274
|
+
return '0';
|
|
275
|
+
}
|
|
276
|
+
return `${value}px`;
|
|
219
277
|
}
|
|
@@ -25,7 +25,7 @@ export class Layout {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
export class LayoutDataGrid extends Layout {
|
|
28
|
-
static elements =
|
|
28
|
+
static elements = ['scroller', 'container', 'content', 'positioner', 'scrollbarVertical', 'scrollbarHorizontal'];
|
|
29
29
|
use(store, _params, _api, layoutParams) {
|
|
30
30
|
const {
|
|
31
31
|
scrollerRef,
|
|
@@ -40,7 +40,7 @@ export class LayoutDataGrid extends Layout {
|
|
|
40
40
|
scrollbarHorizontalRef
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
static selectors =
|
|
43
|
+
static selectors = {
|
|
44
44
|
containerProps: createSelectorMemoized(Virtualization.selectors.context, context => ({
|
|
45
45
|
ref: context.containerRef
|
|
46
46
|
})),
|
|
@@ -57,19 +57,58 @@ export class LayoutDataGrid extends Layout {
|
|
|
57
57
|
// https://github.com/mui/mui-x/pull/13891#discussion_r1683416024
|
|
58
58
|
tabIndex: platform.isFirefox ? -1 : undefined
|
|
59
59
|
})),
|
|
60
|
+
scrollerContentProps: createSelectorMemoized(Virtualization.selectors.layoutMode, Dimensions.selectors.dimensions, Dimensions.selectors.needsVerticalScrollbar, Dimensions.selectors.needsHorizontalScrollbar, (layoutMode, dimensions, needsVerticalScrollbar, needsHorizontalScrollbar) => {
|
|
61
|
+
let style;
|
|
62
|
+
if (layoutMode === 'controlled') {
|
|
63
|
+
const {
|
|
64
|
+
contentSize,
|
|
65
|
+
scrollbarSize,
|
|
66
|
+
topContainerHeight,
|
|
67
|
+
bottomContainerHeight,
|
|
68
|
+
minimalContentHeight,
|
|
69
|
+
columnsTotalWidth
|
|
70
|
+
} = dimensions;
|
|
71
|
+
const verticalScrollbarSize = needsVerticalScrollbar ? scrollbarSize : 0;
|
|
72
|
+
const horizontalScrollbarSize = needsHorizontalScrollbar ? scrollbarSize : 0;
|
|
73
|
+
const contentHeight = contentSize.height === 0 ? minimalContentHeight : contentSize.height;
|
|
74
|
+
const width = needsHorizontalScrollbar ? verticalScrollbarSize + columnsTotalWidth : 'auto';
|
|
75
|
+
const height = cssAdd(cssAdd(cssAdd(contentHeight, topContainerHeight), bottomContainerHeight), horizontalScrollbarSize);
|
|
76
|
+
style = {
|
|
77
|
+
width,
|
|
78
|
+
height,
|
|
79
|
+
flex: '0 0 auto'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
style,
|
|
84
|
+
role: 'presentation'
|
|
85
|
+
};
|
|
86
|
+
}),
|
|
87
|
+
viewportProps: createSelectorMemoized(Dimensions.selectors.dimensions, dimensions => ({
|
|
88
|
+
style: {
|
|
89
|
+
width: dimensions.viewportOuterSize.width,
|
|
90
|
+
height: dimensions.viewportOuterSize.height
|
|
91
|
+
},
|
|
92
|
+
role: 'presentation'
|
|
93
|
+
})),
|
|
60
94
|
contentProps: createSelectorMemoized(Dimensions.selectors.contentHeight, Dimensions.selectors.minimalContentHeight, Dimensions.selectors.columnsTotalWidth, Dimensions.selectors.needsHorizontalScrollbar, (contentHeight, minimalContentHeight, columnsTotalWidth, needsHorizontalScrollbar) => ({
|
|
61
95
|
style: {
|
|
62
96
|
width: needsHorizontalScrollbar ? columnsTotalWidth : 'auto',
|
|
63
|
-
|
|
64
|
-
|
|
97
|
+
height: contentHeight === 0 ? minimalContentHeight : contentHeight,
|
|
98
|
+
flex: '0 0 auto'
|
|
65
99
|
},
|
|
66
100
|
role: 'presentation'
|
|
67
101
|
})),
|
|
68
|
-
positionerProps: createSelectorMemoized(Virtualization.selectors.offsetTop, offsetTop => ({
|
|
102
|
+
positionerProps: createSelectorMemoized(Virtualization.selectors.layoutMode, Virtualization.selectors.offsetTop, Virtualization.selectors.scrollPosition, (layoutMode, offsetTop, scrollPosition) => ({
|
|
69
103
|
style: {
|
|
70
|
-
transform: `translate3d(0, ${offsetTop}px, 0)`
|
|
104
|
+
transform: layoutMode === 'uncontrolled' ? `translate3d(0, ${offsetTop}px, 0)` : `translate3d(${-scrollPosition.current.left}px, ${offsetTop - scrollPosition.current.top}px, 0)`
|
|
71
105
|
}
|
|
72
106
|
})),
|
|
107
|
+
containerVerticalProps: createSelectorMemoized(Virtualization.selectors.layoutMode, Virtualization.selectors.scrollPosition, (layoutMode, scrollPosition) => layoutMode === 'uncontrolled' ? undefined : {
|
|
108
|
+
style: {
|
|
109
|
+
transform: `translate3d(${-scrollPosition.current.left}px, 0, 0)`
|
|
110
|
+
}
|
|
111
|
+
}),
|
|
73
112
|
scrollbarHorizontalProps: createSelectorMemoized(Virtualization.selectors.context, Virtualization.selectors.scrollPosition, (context, scrollPosition) => ({
|
|
74
113
|
ref: context.scrollbarHorizontalRef,
|
|
75
114
|
scrollPosition
|
|
@@ -81,7 +120,7 @@ export class LayoutDataGrid extends Layout {
|
|
|
81
120
|
scrollAreaProps: createSelectorMemoized(Virtualization.selectors.scrollPosition, scrollPosition => ({
|
|
82
121
|
scrollPosition
|
|
83
122
|
}))
|
|
84
|
-
}
|
|
123
|
+
};
|
|
85
124
|
}
|
|
86
125
|
|
|
87
126
|
// The current virtualizer API is exposed on one of the DataGrid slots, so we need to keep
|
|
@@ -94,24 +133,30 @@ export class LayoutDataGridLegacy extends LayoutDataGrid {
|
|
|
94
133
|
super.use(store, _params, _api, layoutParams);
|
|
95
134
|
const containerProps = store.use(LayoutDataGrid.selectors.containerProps);
|
|
96
135
|
const scrollerProps = store.use(LayoutDataGrid.selectors.scrollerProps);
|
|
136
|
+
const scrollerContentProps = store.use(LayoutDataGrid.selectors.scrollerContentProps);
|
|
137
|
+
const viewportProps = store.use(LayoutDataGrid.selectors.viewportProps);
|
|
97
138
|
const contentProps = store.use(LayoutDataGrid.selectors.contentProps);
|
|
98
139
|
const positionerProps = store.use(LayoutDataGrid.selectors.positionerProps);
|
|
99
140
|
const scrollbarVerticalProps = store.use(LayoutDataGrid.selectors.scrollbarVerticalProps);
|
|
100
141
|
const scrollbarHorizontalProps = store.use(LayoutDataGrid.selectors.scrollbarHorizontalProps);
|
|
101
142
|
const scrollAreaProps = store.use(LayoutDataGrid.selectors.scrollAreaProps);
|
|
143
|
+
const containerVerticalProps = store.use(LayoutDataGrid.selectors.containerVerticalProps);
|
|
102
144
|
return {
|
|
103
145
|
getContainerProps: () => containerProps,
|
|
104
146
|
getScrollerProps: () => scrollerProps,
|
|
147
|
+
getScrollerContentProps: () => scrollerContentProps,
|
|
148
|
+
getViewportProps: () => viewportProps,
|
|
105
149
|
getContentProps: () => contentProps,
|
|
106
150
|
getPositionerProps: () => positionerProps,
|
|
107
151
|
getScrollbarVerticalProps: () => scrollbarVerticalProps,
|
|
108
152
|
getScrollbarHorizontalProps: () => scrollbarHorizontalProps,
|
|
109
|
-
getScrollAreaProps: () => scrollAreaProps
|
|
153
|
+
getScrollAreaProps: () => scrollAreaProps,
|
|
154
|
+
getContainerVerticalProps: () => containerVerticalProps
|
|
110
155
|
};
|
|
111
156
|
}
|
|
112
157
|
}
|
|
113
158
|
export class LayoutList extends Layout {
|
|
114
|
-
static elements =
|
|
159
|
+
static elements = ['scroller', 'container', 'content', 'positioner'];
|
|
115
160
|
use(store, _params, _api, layoutParams) {
|
|
116
161
|
const {
|
|
117
162
|
scrollerRef,
|
|
@@ -122,7 +167,7 @@ export class LayoutList extends Layout {
|
|
|
122
167
|
mergedRef
|
|
123
168
|
};
|
|
124
169
|
}
|
|
125
|
-
static selectors =
|
|
170
|
+
static selectors = {
|
|
126
171
|
containerProps: createSelectorMemoized(Virtualization.selectors.context, Dimensions.selectors.autoHeight, Dimensions.selectors.needsHorizontalScrollbar, (context, autoHeight, needsHorizontalScrollbar) => ({
|
|
127
172
|
ref: context.mergedRef,
|
|
128
173
|
style: {
|
|
@@ -135,26 +180,24 @@ export class LayoutList extends Layout {
|
|
|
135
180
|
// https://github.com/mui/mui-x/pull/13891#discussion_r1683416024
|
|
136
181
|
tabIndex: platform.isFirefox ? -1 : undefined
|
|
137
182
|
})),
|
|
138
|
-
contentProps: createSelectorMemoized(Dimensions.selectors.contentHeight, contentHeight => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
};
|
|
151
|
-
}),
|
|
183
|
+
contentProps: createSelectorMemoized(Dimensions.selectors.contentHeight, contentHeight => ({
|
|
184
|
+
style: {
|
|
185
|
+
position: 'absolute',
|
|
186
|
+
display: 'inline-block',
|
|
187
|
+
width: '100%',
|
|
188
|
+
height: contentHeight,
|
|
189
|
+
top: 0,
|
|
190
|
+
left: 0,
|
|
191
|
+
zIndex: -1
|
|
192
|
+
},
|
|
193
|
+
role: 'presentation'
|
|
194
|
+
})),
|
|
152
195
|
positionerProps: createSelectorMemoized(Virtualization.selectors.offsetTop, offsetTop => ({
|
|
153
196
|
style: {
|
|
154
197
|
height: offsetTop
|
|
155
198
|
}
|
|
156
199
|
}))
|
|
157
|
-
}
|
|
200
|
+
};
|
|
158
201
|
}
|
|
159
202
|
function useScrollbarRefCallback(scrollerRef, refSetter, scrollProperty) {
|
|
160
203
|
const isLocked = React.useRef(false);
|
|
@@ -206,4 +249,19 @@ function useScrollbarRefCallback(scrollerRef, refSetter, scrollProperty) {
|
|
|
206
249
|
scrollbar.removeEventListener('scroll', onScrollbarScroll);
|
|
207
250
|
};
|
|
208
251
|
});
|
|
252
|
+
}
|
|
253
|
+
function cssAdd(a, b) {
|
|
254
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
255
|
+
return a + b;
|
|
256
|
+
}
|
|
257
|
+
return `calc(${valueToCSSString(a)} + ${valueToCSSString(b)})`;
|
|
258
|
+
}
|
|
259
|
+
function valueToCSSString(value) {
|
|
260
|
+
if (typeof value === 'string') {
|
|
261
|
+
return value;
|
|
262
|
+
}
|
|
263
|
+
if (typeof value === 'undefined') {
|
|
264
|
+
return '0';
|
|
265
|
+
}
|
|
266
|
+
return `${value}px`;
|
|
209
267
|
}
|
|
@@ -15,6 +15,13 @@ export type VirtualizationParams = {
|
|
|
15
15
|
/** The column buffer in pixels to render before and after the viewport.
|
|
16
16
|
* @default 150 */
|
|
17
17
|
columnBufferPx?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Controls how the container and render zones are positioned:
|
|
20
|
+
* - 'uncontrolled': uses CSS sticky positioning (default)
|
|
21
|
+
* - 'controlled': uses CSS absolute positioning with JS-computed offsets
|
|
22
|
+
* @default 'uncontrolled'
|
|
23
|
+
*/
|
|
24
|
+
layoutMode?: 'controlled' | 'uncontrolled';
|
|
18
25
|
};
|
|
19
26
|
export type VirtualizationState<K extends string = string> = {
|
|
20
27
|
enabled: boolean;
|
|
@@ -26,6 +33,7 @@ export type VirtualizationState<K extends string = string> = {
|
|
|
26
33
|
scrollPosition: {
|
|
27
34
|
current: ScrollPosition;
|
|
28
35
|
};
|
|
36
|
+
layoutMode: 'controlled' | 'uncontrolled';
|
|
29
37
|
};
|
|
30
38
|
export declare const EMPTY_RENDER_CONTEXT: {
|
|
31
39
|
firstRowIndex: number;
|
|
@@ -46,9 +54,18 @@ export declare const Virtualization: {
|
|
|
46
54
|
container: React.RefObject<HTMLElement | null>;
|
|
47
55
|
} & Record<string, React.RefObject<HTMLElement | null>>>> & Dimensions.State) => number;
|
|
48
56
|
context: (state: BaseState) => Record<string, any>;
|
|
57
|
+
layoutMode: (state: BaseState) => "controlled" | "uncontrolled";
|
|
49
58
|
scrollPosition: (state: BaseState) => {
|
|
50
59
|
current: ScrollPosition;
|
|
51
60
|
};
|
|
61
|
+
pinnedLeftOffsetSelector: (args_0: Virtualization.State<Layout<{
|
|
62
|
+
scroller: React.RefObject<HTMLElement | null>;
|
|
63
|
+
container: React.RefObject<HTMLElement | null>;
|
|
64
|
+
} & Record<string, React.RefObject<HTMLElement | null>>>> & Dimensions.State) => number;
|
|
65
|
+
pinnedRightOffsetSelector: (args_0: Virtualization.State<Layout<{
|
|
66
|
+
scroller: React.RefObject<HTMLElement | null>;
|
|
67
|
+
container: React.RefObject<HTMLElement | null>;
|
|
68
|
+
} & Record<string, React.RefObject<HTMLElement | null>>>> & Dimensions.State) => number;
|
|
52
69
|
};
|
|
53
70
|
};
|
|
54
71
|
export declare namespace Virtualization {
|
|
@@ -83,6 +100,6 @@ declare function useVirtualization(store: Store<BaseState>, params: ParamsWithDe
|
|
|
83
100
|
scheduleUpdateRenderContext: () => void;
|
|
84
101
|
};
|
|
85
102
|
export declare function areRenderContextsEqual(context1: RenderContext, context2: RenderContext): boolean;
|
|
86
|
-
export declare function computeOffsetLeft(columnPositions: number[], renderContext: ColumnsRenderContext, pinnedLeftLength: number): number;
|
|
103
|
+
export declare function computeOffsetLeft(columnPositions: number[], renderContext: ColumnsRenderContext, pinnedLeftLength: number, layoutMode?: VirtualizationState['layoutMode']): number;
|
|
87
104
|
export declare function roundToDecimalPlaces(value: number, decimals: number): number;
|
|
88
105
|
export {};
|
|
@@ -15,6 +15,13 @@ export type VirtualizationParams = {
|
|
|
15
15
|
/** The column buffer in pixels to render before and after the viewport.
|
|
16
16
|
* @default 150 */
|
|
17
17
|
columnBufferPx?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Controls how the container and render zones are positioned:
|
|
20
|
+
* - 'uncontrolled': uses CSS sticky positioning (default)
|
|
21
|
+
* - 'controlled': uses CSS absolute positioning with JS-computed offsets
|
|
22
|
+
* @default 'uncontrolled'
|
|
23
|
+
*/
|
|
24
|
+
layoutMode?: 'controlled' | 'uncontrolled';
|
|
18
25
|
};
|
|
19
26
|
export type VirtualizationState<K extends string = string> = {
|
|
20
27
|
enabled: boolean;
|
|
@@ -26,6 +33,7 @@ export type VirtualizationState<K extends string = string> = {
|
|
|
26
33
|
scrollPosition: {
|
|
27
34
|
current: ScrollPosition;
|
|
28
35
|
};
|
|
36
|
+
layoutMode: 'controlled' | 'uncontrolled';
|
|
29
37
|
};
|
|
30
38
|
export declare const EMPTY_RENDER_CONTEXT: {
|
|
31
39
|
firstRowIndex: number;
|
|
@@ -46,9 +54,18 @@ export declare const Virtualization: {
|
|
|
46
54
|
container: React.RefObject<HTMLElement | null>;
|
|
47
55
|
} & Record<string, React.RefObject<HTMLElement | null>>>> & Dimensions.State) => number;
|
|
48
56
|
context: (state: BaseState) => Record<string, any>;
|
|
57
|
+
layoutMode: (state: BaseState) => "controlled" | "uncontrolled";
|
|
49
58
|
scrollPosition: (state: BaseState) => {
|
|
50
59
|
current: ScrollPosition;
|
|
51
60
|
};
|
|
61
|
+
pinnedLeftOffsetSelector: (args_0: Virtualization.State<Layout<{
|
|
62
|
+
scroller: React.RefObject<HTMLElement | null>;
|
|
63
|
+
container: React.RefObject<HTMLElement | null>;
|
|
64
|
+
} & Record<string, React.RefObject<HTMLElement | null>>>> & Dimensions.State) => number;
|
|
65
|
+
pinnedRightOffsetSelector: (args_0: Virtualization.State<Layout<{
|
|
66
|
+
scroller: React.RefObject<HTMLElement | null>;
|
|
67
|
+
container: React.RefObject<HTMLElement | null>;
|
|
68
|
+
} & Record<string, React.RefObject<HTMLElement | null>>>> & Dimensions.State) => number;
|
|
52
69
|
};
|
|
53
70
|
};
|
|
54
71
|
export declare namespace Virtualization {
|
|
@@ -83,6 +100,6 @@ declare function useVirtualization(store: Store<BaseState>, params: ParamsWithDe
|
|
|
83
100
|
scheduleUpdateRenderContext: () => void;
|
|
84
101
|
};
|
|
85
102
|
export declare function areRenderContextsEqual(context1: RenderContext, context2: RenderContext): boolean;
|
|
86
|
-
export declare function computeOffsetLeft(columnPositions: number[], renderContext: ColumnsRenderContext, pinnedLeftLength: number): number;
|
|
103
|
+
export declare function computeOffsetLeft(columnPositions: number[], renderContext: ColumnsRenderContext, pinnedLeftLength: number, layoutMode?: VirtualizationState['layoutMode']): number;
|
|
87
104
|
export declare function roundToDecimalPlaces(value: number, decimals: number): number;
|
|
88
105
|
export {};
|
|
@@ -42,14 +42,23 @@ const EMPTY_RENDER_CONTEXT = exports.EMPTY_RENDER_CONTEXT = {
|
|
|
42
42
|
};
|
|
43
43
|
const selectors = (() => {
|
|
44
44
|
const firstRowIndexSelector = (0, _store.createSelector)(state => state.virtualization.renderContext.firstRowIndex);
|
|
45
|
+
const scrollPositionSelector = (0, _store.createSelector)(state => state.virtualization.scrollPosition);
|
|
46
|
+
const layoutModeSelector = (0, _store.createSelector)(state => state.virtualization.layoutMode);
|
|
45
47
|
return {
|
|
46
48
|
store: (0, _store.createSelector)(state => state.virtualization),
|
|
47
49
|
renderContext: (0, _store.createSelector)(state => state.virtualization.renderContext),
|
|
48
50
|
enabledForRows: (0, _store.createSelector)(state => state.virtualization.enabledForRows),
|
|
49
51
|
enabledForColumns: (0, _store.createSelector)(state => state.virtualization.enabledForColumns),
|
|
50
|
-
offsetTop: (0, _store.createSelector)(_dimensions.Dimensions.selectors.rowPositions, firstRowIndexSelector, (rowPositions, firstRowIndex) =>
|
|
52
|
+
offsetTop: (0, _store.createSelector)(layoutModeSelector, _dimensions.Dimensions.selectors.dimensions, _dimensions.Dimensions.selectors.rowPositions, firstRowIndexSelector, (layoutMode, dimensions, rowPositions, firstRowIndex) => {
|
|
53
|
+
return (layoutMode === 'uncontrolled' ? dimensions.topContainerHeight : 0) + (rowPositions[firstRowIndex] ?? 0);
|
|
54
|
+
}),
|
|
51
55
|
context: (0, _store.createSelector)(state => state.virtualization.context),
|
|
52
|
-
|
|
56
|
+
layoutMode: layoutModeSelector,
|
|
57
|
+
scrollPosition: scrollPositionSelector,
|
|
58
|
+
pinnedLeftOffsetSelector: (0, _store.createSelector)(scrollPositionSelector, scrollPosition => scrollPosition.current.left),
|
|
59
|
+
pinnedRightOffsetSelector: (0, _store.createSelector)(scrollPositionSelector, _dimensions.Dimensions.selectors.dimensions, _dimensions.Dimensions.selectors.columnsTotalWidth, _dimensions.Dimensions.selectors.needsVerticalScrollbar, (scrollPosition, dimensions, columnsTotalWidth, needsVerticalScrollbar) => {
|
|
60
|
+
return Math.max(columnsTotalWidth, dimensions.viewportOuterSize.width) - dimensions.viewportOuterSize.width - scrollPosition.current.left + (needsVerticalScrollbar ? dimensions.scrollbarSize : 0);
|
|
61
|
+
})
|
|
53
62
|
};
|
|
54
63
|
})();
|
|
55
64
|
const Virtualization = exports.Virtualization = {
|
|
@@ -68,7 +77,8 @@ function initializeState(params) {
|
|
|
68
77
|
context: {},
|
|
69
78
|
scrollPosition: {
|
|
70
79
|
current: _models.ScrollPosition.EMPTY
|
|
71
|
-
}
|
|
80
|
+
},
|
|
81
|
+
layoutMode: params.virtualization.layoutMode ?? 'uncontrolled'
|
|
72
82
|
}, params.initialState?.virtualization),
|
|
73
83
|
// FIXME: refactor once the state shape is settled
|
|
74
84
|
getters: null
|
|
@@ -365,7 +375,7 @@ function useVirtualization(store, params, api) {
|
|
|
365
375
|
}
|
|
366
376
|
const isVirtualFocusRow = rowIndexInPage === virtualRowIndex;
|
|
367
377
|
const isVirtualFocusColumn = focusedVirtualCell?.rowIndex === rowIndex;
|
|
368
|
-
const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext, pinnedColumns.left.length);
|
|
378
|
+
const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext, pinnedColumns.left.length, store.state.virtualization.layoutMode);
|
|
369
379
|
const showBottomBorder = isLastVisibleInSection && rowParams.position === 'top';
|
|
370
380
|
const firstColumnIndex = currentRenderContext.firstColumnIndex;
|
|
371
381
|
const lastColumnIndex = currentRenderContext.lastColumnIndex;
|
|
@@ -735,9 +745,14 @@ function areRenderContextsEqual(context1, context2) {
|
|
|
735
745
|
}
|
|
736
746
|
return context1.firstRowIndex === context2.firstRowIndex && context1.lastRowIndex === context2.lastRowIndex && context1.firstColumnIndex === context2.firstColumnIndex && context1.lastColumnIndex === context2.lastColumnIndex;
|
|
737
747
|
}
|
|
738
|
-
function computeOffsetLeft(columnPositions, renderContext, pinnedLeftLength) {
|
|
739
|
-
|
|
740
|
-
|
|
748
|
+
function computeOffsetLeft(columnPositions, renderContext, pinnedLeftLength, layoutMode = 'uncontrolled') {
|
|
749
|
+
let offset = columnPositions[renderContext.firstColumnIndex] ?? 0;
|
|
750
|
+
/* CSS sticky leaves elements in the normal flow of the DOM, so we
|
|
751
|
+
* don't need to add the offset of the pinned columns. */
|
|
752
|
+
if (layoutMode === 'uncontrolled') {
|
|
753
|
+
offset -= columnPositions[pinnedLeftLength] ?? 0;
|
|
754
|
+
}
|
|
755
|
+
return Math.abs(offset);
|
|
741
756
|
}
|
|
742
757
|
function bufferForDirection(isRtl, direction, rowBufferPx, columnBufferPx, verticalBuffer, horizontalBuffer) {
|
|
743
758
|
if (isRtl) {
|
|
@@ -33,14 +33,23 @@ export const EMPTY_RENDER_CONTEXT = {
|
|
|
33
33
|
};
|
|
34
34
|
const selectors = (() => {
|
|
35
35
|
const firstRowIndexSelector = createSelector(state => state.virtualization.renderContext.firstRowIndex);
|
|
36
|
+
const scrollPositionSelector = createSelector(state => state.virtualization.scrollPosition);
|
|
37
|
+
const layoutModeSelector = createSelector(state => state.virtualization.layoutMode);
|
|
36
38
|
return {
|
|
37
39
|
store: createSelector(state => state.virtualization),
|
|
38
40
|
renderContext: createSelector(state => state.virtualization.renderContext),
|
|
39
41
|
enabledForRows: createSelector(state => state.virtualization.enabledForRows),
|
|
40
42
|
enabledForColumns: createSelector(state => state.virtualization.enabledForColumns),
|
|
41
|
-
offsetTop: createSelector(Dimensions.selectors.rowPositions, firstRowIndexSelector, (rowPositions, firstRowIndex) =>
|
|
43
|
+
offsetTop: createSelector(layoutModeSelector, Dimensions.selectors.dimensions, Dimensions.selectors.rowPositions, firstRowIndexSelector, (layoutMode, dimensions, rowPositions, firstRowIndex) => {
|
|
44
|
+
return (layoutMode === 'uncontrolled' ? dimensions.topContainerHeight : 0) + (rowPositions[firstRowIndex] ?? 0);
|
|
45
|
+
}),
|
|
42
46
|
context: createSelector(state => state.virtualization.context),
|
|
43
|
-
|
|
47
|
+
layoutMode: layoutModeSelector,
|
|
48
|
+
scrollPosition: scrollPositionSelector,
|
|
49
|
+
pinnedLeftOffsetSelector: createSelector(scrollPositionSelector, scrollPosition => scrollPosition.current.left),
|
|
50
|
+
pinnedRightOffsetSelector: createSelector(scrollPositionSelector, Dimensions.selectors.dimensions, Dimensions.selectors.columnsTotalWidth, Dimensions.selectors.needsVerticalScrollbar, (scrollPosition, dimensions, columnsTotalWidth, needsVerticalScrollbar) => {
|
|
51
|
+
return Math.max(columnsTotalWidth, dimensions.viewportOuterSize.width) - dimensions.viewportOuterSize.width - scrollPosition.current.left + (needsVerticalScrollbar ? dimensions.scrollbarSize : 0);
|
|
52
|
+
})
|
|
44
53
|
};
|
|
45
54
|
})();
|
|
46
55
|
export const Virtualization = {
|
|
@@ -59,7 +68,8 @@ function initializeState(params) {
|
|
|
59
68
|
context: {},
|
|
60
69
|
scrollPosition: {
|
|
61
70
|
current: ScrollPosition.EMPTY
|
|
62
|
-
}
|
|
71
|
+
},
|
|
72
|
+
layoutMode: params.virtualization.layoutMode ?? 'uncontrolled'
|
|
63
73
|
}, params.initialState?.virtualization),
|
|
64
74
|
// FIXME: refactor once the state shape is settled
|
|
65
75
|
getters: null
|
|
@@ -356,7 +366,7 @@ function useVirtualization(store, params, api) {
|
|
|
356
366
|
}
|
|
357
367
|
const isVirtualFocusRow = rowIndexInPage === virtualRowIndex;
|
|
358
368
|
const isVirtualFocusColumn = focusedVirtualCell?.rowIndex === rowIndex;
|
|
359
|
-
const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext, pinnedColumns.left.length);
|
|
369
|
+
const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext, pinnedColumns.left.length, store.state.virtualization.layoutMode);
|
|
360
370
|
const showBottomBorder = isLastVisibleInSection && rowParams.position === 'top';
|
|
361
371
|
const firstColumnIndex = currentRenderContext.firstColumnIndex;
|
|
362
372
|
const lastColumnIndex = currentRenderContext.lastColumnIndex;
|
|
@@ -726,9 +736,14 @@ export function areRenderContextsEqual(context1, context2) {
|
|
|
726
736
|
}
|
|
727
737
|
return context1.firstRowIndex === context2.firstRowIndex && context1.lastRowIndex === context2.lastRowIndex && context1.firstColumnIndex === context2.firstColumnIndex && context1.lastColumnIndex === context2.lastColumnIndex;
|
|
728
738
|
}
|
|
729
|
-
export function computeOffsetLeft(columnPositions, renderContext, pinnedLeftLength) {
|
|
730
|
-
|
|
731
|
-
|
|
739
|
+
export function computeOffsetLeft(columnPositions, renderContext, pinnedLeftLength, layoutMode = 'uncontrolled') {
|
|
740
|
+
let offset = columnPositions[renderContext.firstColumnIndex] ?? 0;
|
|
741
|
+
/* CSS sticky leaves elements in the normal flow of the DOM, so we
|
|
742
|
+
* don't need to add the offset of the pinned columns. */
|
|
743
|
+
if (layoutMode === 'uncontrolled') {
|
|
744
|
+
offset -= columnPositions[pinnedLeftLength] ?? 0;
|
|
745
|
+
}
|
|
746
|
+
return Math.abs(offset);
|
|
732
747
|
}
|
|
733
748
|
function bufferForDirection(isRtl, direction, rowBufferPx, columnBufferPx, verticalBuffer, horizontalBuffer) {
|
|
734
749
|
if (isRtl) {
|
package/index.js
CHANGED
package/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/x-virtualizer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0-alpha.0",
|
|
4
4
|
"author": "MUI Team",
|
|
5
5
|
"description": "MUI virtualization library",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@babel/runtime": "^7.28.6",
|
|
31
|
-
"@mui/utils": "
|
|
32
|
-
"@mui/x-internals": "9.0.0
|
|
31
|
+
"@mui/utils": "9.0.0",
|
|
32
|
+
"@mui/x-internals": "^9.0.0"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|