@mui/x-virtualizer 0.1.1 → 0.1.3
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 +182 -0
- package/esm/features/colspan.d.ts +4 -0
- package/esm/features/colspan.js +4 -3
- package/esm/features/dimensions.d.ts +11 -1
- package/esm/features/dimensions.js +30 -49
- package/esm/features/virtualization.d.ts +17 -10
- package/esm/features/virtualization.js +55 -74
- package/esm/index.js +1 -1
- package/esm/models/core.d.ts +10 -4
- package/esm/models/core.js +20 -8
- package/esm/models/dimensions.d.ts +2 -33
- package/esm/useVirtualizer.d.ts +35 -54
- package/features/colspan.d.ts +4 -0
- package/features/colspan.js +4 -3
- package/features/dimensions.d.ts +11 -1
- package/features/dimensions.js +28 -48
- package/features/virtualization.d.ts +17 -10
- package/features/virtualization.js +55 -74
- package/index.js +1 -1
- package/models/core.d.ts +10 -4
- package/models/core.js +21 -9
- package/models/dimensions.d.ts +2 -33
- package/package.json +19 -9
- package/useVirtualizer.d.ts +35 -54
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,188 @@
|
|
|
5
5
|
All notable changes to this project will be documented in this file.
|
|
6
6
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
7
7
|
|
|
8
|
+
## 8.10.2
|
|
9
|
+
|
|
10
|
+
_Aug 20, 2025_
|
|
11
|
+
|
|
12
|
+
We'd like to extend a big thank you to the 10 contributors who made this release possible. Here are some highlights ✨:
|
|
13
|
+
|
|
14
|
+
- 🌎 Improve Finnish (fi-FI) locale on the Data Grid
|
|
15
|
+
|
|
16
|
+
Special thanks go out to the community members for their valuable contributions:
|
|
17
|
+
@lauri-heinonen-2025-04, @Methuselah96, @sai6855, @wilcoschoneveld
|
|
18
|
+
|
|
19
|
+
The following are all team members who have contributed to this release:
|
|
20
|
+
@alexfauquette, @cherniavskii, @flaviendelangle, @Janpot, @oliviertassinari, @rita-codes
|
|
21
|
+
|
|
22
|
+
### Data Grid
|
|
23
|
+
|
|
24
|
+
#### `@mui/x-data-grid@8.10.2`
|
|
25
|
+
|
|
26
|
+
- [DataGrid] Fix display for `<GridEditSingleSelect />` when `density='compact'` (#19249) @sai6855
|
|
27
|
+
- [DataGrid] Fix column header sortable classname when using `disableColumnSorting` (#19222) @wilcoschoneveld
|
|
28
|
+
- [l10n] Improve finnish (fi-FI) locale (#19163) @lauri-heinonen-2025-04
|
|
29
|
+
|
|
30
|
+
#### `@mui/x-data-grid-pro@8.10.2` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
31
|
+
|
|
32
|
+
Same changes as in `@mui/x-data-grid@8.10.2`, plus:
|
|
33
|
+
|
|
34
|
+
- [DataGridPro] Fix quick filter not working in List View mode (#19254) @cherniavskii
|
|
35
|
+
|
|
36
|
+
#### `@mui/x-data-grid-premium@8.10.2` [](https://mui.com/r/x-premium-svg-link "Premium plan")
|
|
37
|
+
|
|
38
|
+
Same changes as in `@mui/x-data-grid-pro@8.10.2`.
|
|
39
|
+
|
|
40
|
+
### Date and Time Pickers
|
|
41
|
+
|
|
42
|
+
#### `@mui/x-date-pickers@8.10.2`
|
|
43
|
+
|
|
44
|
+
Internal changes.
|
|
45
|
+
|
|
46
|
+
#### `@mui/x-date-pickers-pro@8.10.2` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
47
|
+
|
|
48
|
+
Same changes as in `@mui/x-date-pickers@8.10.2`.
|
|
49
|
+
|
|
50
|
+
### Charts
|
|
51
|
+
|
|
52
|
+
#### `@mui/x-charts@8.10.2`
|
|
53
|
+
|
|
54
|
+
Internal changes.
|
|
55
|
+
|
|
56
|
+
#### `@mui/x-charts-pro@8.10.2` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
57
|
+
|
|
58
|
+
Same changes as in `@mui/x-charts@8.10.2`.
|
|
59
|
+
|
|
60
|
+
### Tree View
|
|
61
|
+
|
|
62
|
+
#### `@mui/x-tree-view@8.10.2`
|
|
63
|
+
|
|
64
|
+
- [tree view] Add `aria-hidden` to the Tree Item Checkbox (#19246) @flaviendelangle
|
|
65
|
+
|
|
66
|
+
#### `@mui/x-tree-view-pro@8.10.2` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
67
|
+
|
|
68
|
+
Same changes as in `@mui/x-tree-view@8.10.2`.
|
|
69
|
+
|
|
70
|
+
### Codemod
|
|
71
|
+
|
|
72
|
+
#### `@mui/x-codemod@8.10.2`
|
|
73
|
+
|
|
74
|
+
Internal changes.
|
|
75
|
+
|
|
76
|
+
### Docs
|
|
77
|
+
|
|
78
|
+
- [docs] Fix links to the pyramid chart (#19250) @alexfauquette
|
|
79
|
+
|
|
80
|
+
### Core
|
|
81
|
+
|
|
82
|
+
- [internal] Avoid script for CI only @oliviertassinari
|
|
83
|
+
- [internal] Fix `renovate.json` @oliviertassinari
|
|
84
|
+
- [internal] Polish renovate config @oliviertassinari
|
|
85
|
+
- [internal] Rename core to internal (#19203) @oliviertassinari
|
|
86
|
+
- [internal] Update link to GitHub labels @oliviertassinari
|
|
87
|
+
|
|
88
|
+
### Miscellaneous
|
|
89
|
+
|
|
90
|
+
- [code-infra] Prepare for incoming `execa` update (#19229) @Janpot
|
|
91
|
+
- [virtualizer] Fix type import (#19192) @Methuselah96
|
|
92
|
+
- [virtualizer] Improve type export (#19192) @Methuselah96
|
|
93
|
+
|
|
94
|
+
## 8.10.1
|
|
95
|
+
|
|
96
|
+
_Aug 15, 2025_
|
|
97
|
+
|
|
98
|
+
We'd like to extend a big thank you to the 8 contributors who made this release possible. Here are some highlights ✨:
|
|
99
|
+
|
|
100
|
+
- 📊 Y-axes can now be grouped by category when using `band` and `point` scales.
|
|
101
|
+
- 📚 Documentation improvements
|
|
102
|
+
|
|
103
|
+
The following are all team members who have contributed to this release:
|
|
104
|
+
@alexfauquette, @bernardobelchior, @Janpot, @JCQuintas, @mnajdova, @oliviertassinari, @prakhargupta1, @romgrk
|
|
105
|
+
|
|
106
|
+
### Data Grid
|
|
107
|
+
|
|
108
|
+
#### `@mui/x-data-grid@8.10.1`
|
|
109
|
+
|
|
110
|
+
- [DataGrid] Fix scroll jumping (#19156) @romgrk
|
|
111
|
+
- [DataGrid] Fix scroll restoration (#19182) @romgrk
|
|
112
|
+
- [DataGrid] Fix "no row with id" error (#19193) @romgrk
|
|
113
|
+
|
|
114
|
+
#### `@mui/x-data-grid-pro@8.10.1` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
115
|
+
|
|
116
|
+
Same changes as in `@mui/x-data-grid@8.10.1`.
|
|
117
|
+
|
|
118
|
+
#### `@mui/x-data-grid-premium@8.10.1` [](https://mui.com/r/x-premium-svg-link "Premium plan")
|
|
119
|
+
|
|
120
|
+
Same changes as in `@mui/x-data-grid-pro@8.10.1`.
|
|
121
|
+
|
|
122
|
+
### Date and Time Pickers
|
|
123
|
+
|
|
124
|
+
#### `@mui/x-date-pickers@8.10.0`
|
|
125
|
+
|
|
126
|
+
Internal changes.
|
|
127
|
+
|
|
128
|
+
#### `@mui/x-date-pickers-pro@8.10.0` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
129
|
+
|
|
130
|
+
Same changes as in `@mui/x-date-pickers@8.10.0`.
|
|
131
|
+
|
|
132
|
+
### Charts
|
|
133
|
+
|
|
134
|
+
- Axes can now be grouped by category when using `band` and `point` scales
|
|
135
|
+
|
|
136
|
+
<img width="643" height="455" alt="Bar chart with y-axis grouped per categories" src="https://github.com/user-attachments/assets/59044afe-bcc5-4152-8bf1-225db0635025" />
|
|
137
|
+
|
|
138
|
+
#### `@mui/x-charts@8.10.1`
|
|
139
|
+
|
|
140
|
+
- [charts] Allow y-axis to be grouped (#19081) @JCQuintas
|
|
141
|
+
- [charts] Fix default axis highlight for axes without data attribute (#18985) @alexfauquette
|
|
142
|
+
- [charts] Fix tooltip mark unexpected wrapping in mobile (#19122) @bernardobelchior
|
|
143
|
+
- [charts] Prevent overflow on charts tooltip (#19123) @bernardobelchior
|
|
144
|
+
|
|
145
|
+
#### `@mui/x-charts-pro@8.10.1` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
146
|
+
|
|
147
|
+
Same changes as in `@mui/x-charts@8.10.1`.
|
|
148
|
+
|
|
149
|
+
### Tree View
|
|
150
|
+
|
|
151
|
+
#### `@mui/x-tree-view@8.10.1`
|
|
152
|
+
|
|
153
|
+
Internal changes.
|
|
154
|
+
|
|
155
|
+
#### `@mui/x-tree-view-pro@8.10.1` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
156
|
+
|
|
157
|
+
Same changes as in `@mui/x-tree-view@8.10.1`.
|
|
158
|
+
|
|
159
|
+
### Codemod
|
|
160
|
+
|
|
161
|
+
#### `@mui/x-codemod@8.10.1`
|
|
162
|
+
|
|
163
|
+
Internal changes.
|
|
164
|
+
|
|
165
|
+
### Docs
|
|
166
|
+
|
|
167
|
+
- [docs] Add all planned charts on the overview page (#19077) @prakhargupta1
|
|
168
|
+
- [docs] Add future charts components link in the sidebar (#19140) @prakhargupta1
|
|
169
|
+
- [docs] Fix Heatmap docs duplicate text (#19138) @JCQuintas
|
|
170
|
+
- [docs] Remove preview from Toolbar & Funnel (#19131) @mnajdova
|
|
171
|
+
- [docs] Reproduce npm sparkline (#19089) @alexfauquette
|
|
172
|
+
|
|
173
|
+
### Core
|
|
174
|
+
|
|
175
|
+
- [core] Fix licensing model name (#19025) @oliviertassinari
|
|
176
|
+
- [core] Fix usage of `:catalog` for `@babel/runtime` (#19028) @oliviertassinari
|
|
177
|
+
- [core] Refactor virtualizer API (#18995) @romgrk
|
|
178
|
+
|
|
179
|
+
### Miscellaneous
|
|
180
|
+
|
|
181
|
+
- [code-infra] Remove namespaces (#19071) @Janpot
|
|
182
|
+
- [code-infra] Fix `fs-extra` removal from `formattedTSDemos` script (#19132) @bernardobelchior
|
|
183
|
+
- [code-infra] Remove unused code and dependency (#19139) @bernardobelchior
|
|
184
|
+
- [code-infra] Replace `fs-extra` with `node:fs` where possible (#19127) @bernardobelchior
|
|
185
|
+
- [internal] Edit, keep `lockFileMaintenance` simple @oliviertassinari
|
|
186
|
+
- [internal] Fix writing style action name @oliviertassinari
|
|
187
|
+
- [internal] Make it clear that `lockFileMaintenance` is enabled @oliviertassinari
|
|
188
|
+
- [support-infra] Remove default issue label (#19104) @oliviertassinari
|
|
189
|
+
|
|
8
190
|
## 8.10.0
|
|
9
191
|
|
|
10
192
|
_Aug 8, 2025_
|
|
@@ -6,6 +6,10 @@ import type { CellColSpanInfo } from "../models/colspan.js";
|
|
|
6
6
|
import { Virtualization } from "./virtualization.js";
|
|
7
7
|
type ColumnIndex = number;
|
|
8
8
|
type ColspanMap = Map<RowId, Record<ColumnIndex, CellColSpanInfo>>;
|
|
9
|
+
export type ColspanParams = {
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
getColspan: (rowId: RowId, column: ColumnWithWidth, columnIndex: integer) => integer;
|
|
12
|
+
};
|
|
9
13
|
export declare const Colspan: {
|
|
10
14
|
initialize: typeof initializeState;
|
|
11
15
|
use: typeof useColspan;
|
package/esm/features/colspan.js
CHANGED
|
@@ -14,6 +14,7 @@ function initializeState(_params) {
|
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
function useColspan(store, params, api) {
|
|
17
|
+
const getColspan = params.colspan?.getColspan;
|
|
17
18
|
const resetColSpan = () => {
|
|
18
19
|
store.state.colspanMap = new Map();
|
|
19
20
|
};
|
|
@@ -22,14 +23,14 @@ function useColspan(store, params, api) {
|
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
// Calculate `colSpan` for each cell in the row
|
|
25
|
-
const calculateColSpan = useEventCallback((rowId, minFirstColumn, maxLastColumn, columns) => {
|
|
26
|
+
const calculateColSpan = useEventCallback(getColspan ? (rowId, minFirstColumn, maxLastColumn, columns) => {
|
|
26
27
|
for (let i = minFirstColumn; i < maxLastColumn; i += 1) {
|
|
27
|
-
const cellProps = calculateCellColSpan(store.state.colspanMap, i, rowId, minFirstColumn, maxLastColumn, columns,
|
|
28
|
+
const cellProps = calculateCellColSpan(store.state.colspanMap, i, rowId, minFirstColumn, maxLastColumn, columns, getColspan);
|
|
28
29
|
if (cellProps.colSpan > 1) {
|
|
29
30
|
i += cellProps.colSpan - 1;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
});
|
|
33
|
+
} : () => {});
|
|
33
34
|
api.calculateColSpan = calculateColSpan;
|
|
34
35
|
return {
|
|
35
36
|
resetColSpan,
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { Store } from '@mui/x-internals/store';
|
|
2
2
|
import { ColumnWithWidth, DimensionsState, RowId, RowsMetaState, Size } from "../models/index.js";
|
|
3
3
|
import type { BaseState, VirtualizerParams } from "../useVirtualizer.js";
|
|
4
|
+
export type DimensionsParams = {
|
|
5
|
+
rowHeight: number;
|
|
6
|
+
columnsTotalWidth: number;
|
|
7
|
+
leftPinnedWidth: number;
|
|
8
|
+
rightPinnedWidth: number;
|
|
9
|
+
topPinnedHeight: number;
|
|
10
|
+
bottomPinnedHeight: number;
|
|
11
|
+
scrollbarSize?: number;
|
|
12
|
+
};
|
|
4
13
|
export declare const Dimensions: {
|
|
5
14
|
initialize: typeof initializeState;
|
|
6
15
|
use: typeof useDimensions;
|
|
@@ -8,6 +17,7 @@ export declare const Dimensions: {
|
|
|
8
17
|
rootSize: (state: BaseState) => Size;
|
|
9
18
|
dimensions: (state: BaseState) => DimensionsState;
|
|
10
19
|
rowHeight: (state: BaseState) => number;
|
|
20
|
+
contentHeight: (state: BaseState) => number;
|
|
11
21
|
rowsMeta: (state: BaseState) => RowsMetaState;
|
|
12
22
|
columnPositions: (_: any, columns: ColumnWithWidth[]) => number[];
|
|
13
23
|
needsHorizontalScrollbar: (state: BaseState) => boolean;
|
|
@@ -25,7 +35,7 @@ export declare namespace Dimensions {
|
|
|
25
35
|
declare function initializeState(params: VirtualizerParams): Dimensions.State;
|
|
26
36
|
declare function useDimensions(store: Store<BaseState>, params: VirtualizerParams, _api: {}): {
|
|
27
37
|
updateDimensions: () => void;
|
|
28
|
-
debouncedUpdateDimensions: ((() => void) & import("@mui/x-internals/throttle
|
|
38
|
+
debouncedUpdateDimensions: ((() => void) & import("@mui/x-internals/throttle").Cancelable) | undefined;
|
|
29
39
|
rowsMeta: {
|
|
30
40
|
getRowHeight: (rowId: RowId) => any;
|
|
31
41
|
setLastMeasuredRowIndex: (index: number) => void;
|
|
@@ -9,8 +9,9 @@ import useEventCallback from '@mui/utils/useEventCallback';
|
|
|
9
9
|
import { throttle } from '@mui/x-internals/throttle';
|
|
10
10
|
import { isDeepEqual } from '@mui/x-internals/isDeepEqual';
|
|
11
11
|
import { roundToDecimalPlaces } from '@mui/x-internals/math';
|
|
12
|
-
import { useStore,
|
|
12
|
+
import { useStore, createSelectorMemoized } from '@mui/x-internals/store';
|
|
13
13
|
import { Size } from "../models/index.js";
|
|
14
|
+
|
|
14
15
|
/* eslint-disable import/export, @typescript-eslint/no-redeclare */
|
|
15
16
|
/* eslint-disable no-underscore-dangle */
|
|
16
17
|
|
|
@@ -24,15 +25,11 @@ const EMPTY_DIMENSIONS = {
|
|
|
24
25
|
hasScrollX: false,
|
|
25
26
|
hasScrollY: false,
|
|
26
27
|
scrollbarSize: 0,
|
|
27
|
-
headerHeight: 0,
|
|
28
|
-
groupHeaderHeight: 0,
|
|
29
|
-
headerFilterHeight: 0,
|
|
30
28
|
rowWidth: 0,
|
|
31
29
|
rowHeight: 0,
|
|
32
30
|
columnsTotalWidth: 0,
|
|
33
31
|
leftPinnedWidth: 0,
|
|
34
32
|
rightPinnedWidth: 0,
|
|
35
|
-
headersTotalHeight: 0,
|
|
36
33
|
topContainerHeight: 0,
|
|
37
34
|
bottomContainerHeight: 0
|
|
38
35
|
};
|
|
@@ -40,6 +37,7 @@ const selectors = {
|
|
|
40
37
|
rootSize: state => state.rootSize,
|
|
41
38
|
dimensions: state => state.dimensions,
|
|
42
39
|
rowHeight: state => state.dimensions.rowHeight,
|
|
40
|
+
contentHeight: state => state.dimensions.contentSize.height,
|
|
43
41
|
rowsMeta: state => state.rowsMeta,
|
|
44
42
|
columnPositions: createSelectorMemoized((_, columns) => {
|
|
45
43
|
const positions = [];
|
|
@@ -87,15 +85,15 @@ function useDimensions(store, params, _api) {
|
|
|
87
85
|
refs,
|
|
88
86
|
dimensions: {
|
|
89
87
|
rowHeight,
|
|
90
|
-
headerHeight,
|
|
91
88
|
columnsTotalWidth,
|
|
92
|
-
groupHeaderHeight,
|
|
93
|
-
headerFilterHeight,
|
|
94
|
-
headersTotalHeight,
|
|
95
89
|
leftPinnedWidth,
|
|
96
|
-
rightPinnedWidth
|
|
97
|
-
|
|
90
|
+
rightPinnedWidth,
|
|
91
|
+
topPinnedHeight,
|
|
92
|
+
bottomPinnedHeight
|
|
93
|
+
},
|
|
94
|
+
onResize
|
|
98
95
|
} = params;
|
|
96
|
+
const containerNode = refs.container.current;
|
|
99
97
|
const updateDimensions = React.useCallback(() => {
|
|
100
98
|
if (isFirstSizing.current) {
|
|
101
99
|
return;
|
|
@@ -106,9 +104,9 @@ function useDimensions(store, params, _api) {
|
|
|
106
104
|
// All the floating point dimensions should be rounded to .1 decimal places to avoid subpixel rendering issues
|
|
107
105
|
// https://github.com/mui/mui-x/issues/9550#issuecomment-1619020477
|
|
108
106
|
// https://github.com/mui/mui-x/issues/15721
|
|
109
|
-
const scrollbarSize = measureScrollbarSize(
|
|
110
|
-
const topContainerHeight =
|
|
111
|
-
const bottomContainerHeight = rowsMeta.pinnedBottomRowsTotalHeight;
|
|
107
|
+
const scrollbarSize = measureScrollbarSize(containerNode, params.dimensions.scrollbarSize);
|
|
108
|
+
const topContainerHeight = topPinnedHeight + rowsMeta.pinnedTopRowsTotalHeight;
|
|
109
|
+
const bottomContainerHeight = bottomPinnedHeight + rowsMeta.pinnedBottomRowsTotalHeight;
|
|
112
110
|
const contentSize = {
|
|
113
111
|
width: columnsTotalWidth,
|
|
114
112
|
height: roundToDecimalPlaces(rowsMeta.currentPageTotalHeight, 1)
|
|
@@ -172,15 +170,11 @@ function useDimensions(store, params, _api) {
|
|
|
172
170
|
hasScrollX,
|
|
173
171
|
hasScrollY,
|
|
174
172
|
scrollbarSize,
|
|
175
|
-
headerHeight,
|
|
176
|
-
groupHeaderHeight,
|
|
177
|
-
headerFilterHeight,
|
|
178
173
|
rowWidth,
|
|
179
174
|
rowHeight,
|
|
180
175
|
columnsTotalWidth,
|
|
181
176
|
leftPinnedWidth,
|
|
182
177
|
rightPinnedWidth,
|
|
183
|
-
headersTotalHeight,
|
|
184
178
|
topContainerHeight,
|
|
185
179
|
bottomContainerHeight
|
|
186
180
|
};
|
|
@@ -191,21 +185,16 @@ function useDimensions(store, params, _api) {
|
|
|
191
185
|
store.update({
|
|
192
186
|
dimensions: newDimensions
|
|
193
187
|
});
|
|
194
|
-
|
|
188
|
+
onResize?.(newDimensions.root);
|
|
189
|
+
}, [store, containerNode, params.dimensions.scrollbarSize, params.autoHeight, onResize, rowHeight, columnsTotalWidth, leftPinnedWidth, rightPinnedWidth, topPinnedHeight, bottomPinnedHeight]);
|
|
195
190
|
const {
|
|
196
|
-
resizeThrottleMs
|
|
197
|
-
onResize
|
|
191
|
+
resizeThrottleMs
|
|
198
192
|
} = params;
|
|
199
193
|
const updateDimensionCallback = useEventCallback(updateDimensions);
|
|
200
|
-
const debouncedUpdateDimensions = React.useMemo(() => resizeThrottleMs > 0 ? throttle(
|
|
201
|
-
updateDimensionCallback();
|
|
202
|
-
onResize?.(store.state.rootSize);
|
|
203
|
-
}, resizeThrottleMs) : undefined, [resizeThrottleMs, onResize, store, updateDimensionCallback]);
|
|
194
|
+
const debouncedUpdateDimensions = React.useMemo(() => resizeThrottleMs > 0 ? throttle(updateDimensionCallback, resizeThrottleMs) : undefined, [resizeThrottleMs, updateDimensionCallback]);
|
|
204
195
|
React.useEffect(() => debouncedUpdateDimensions?.clear, [debouncedUpdateDimensions]);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
useStoreEffect(store, selectors.rootSize, (_, size) => {
|
|
208
|
-
params.onResize?.(size);
|
|
196
|
+
const setRootSize = useEventCallback(rootSize => {
|
|
197
|
+
store.state.rootSize = rootSize;
|
|
209
198
|
if (isFirstSizing.current || !debouncedUpdateDimensions) {
|
|
210
199
|
// We want to initialize the grid dimensions as soon as possible to avoid flickering
|
|
211
200
|
isFirstSizing.current = false;
|
|
@@ -214,6 +203,8 @@ function useDimensions(store, params, _api) {
|
|
|
214
203
|
debouncedUpdateDimensions();
|
|
215
204
|
}
|
|
216
205
|
});
|
|
206
|
+
useLayoutEffect(() => observeRootNode(containerNode, store, setRootSize), [containerNode, store, setRootSize]);
|
|
207
|
+
useLayoutEffect(updateDimensions, [updateDimensions]);
|
|
217
208
|
const rowsMeta = useRowsMeta(store, params, updateDimensions);
|
|
218
209
|
return {
|
|
219
210
|
updateDimensions,
|
|
@@ -250,7 +241,6 @@ function useRowsMeta(store, params, updateDimensions) {
|
|
|
250
241
|
return entry;
|
|
251
242
|
});
|
|
252
243
|
const {
|
|
253
|
-
rowIdToIndexMap,
|
|
254
244
|
applyRowHeight
|
|
255
245
|
} = params;
|
|
256
246
|
const processHeightEntry = React.useCallback(row => {
|
|
@@ -282,12 +272,7 @@ function useRowsMeta(store, params, updateDimensions) {
|
|
|
282
272
|
}
|
|
283
273
|
}
|
|
284
274
|
if (getRowSpacing) {
|
|
285
|
-
const
|
|
286
|
-
const spacing = getRowSpacing(row, {
|
|
287
|
-
isFirstVisible: indexRelativeToCurrentPage === 0,
|
|
288
|
-
isLastVisible: indexRelativeToCurrentPage === rows.length - 1,
|
|
289
|
-
indexRelativeToCurrentPage
|
|
290
|
-
});
|
|
275
|
+
const spacing = getRowSpacing(row);
|
|
291
276
|
entry.spacingTop = spacing.top ?? 0;
|
|
292
277
|
entry.spacingBottom = spacing.bottom ?? 0;
|
|
293
278
|
} else {
|
|
@@ -296,17 +281,17 @@ function useRowsMeta(store, params, updateDimensions) {
|
|
|
296
281
|
}
|
|
297
282
|
applyRowHeight?.(entry, row);
|
|
298
283
|
return entry;
|
|
299
|
-
}, [store,
|
|
284
|
+
}, [store, getRowHeightProp, getRowHeightEntry, getEstimatedRowHeight, rowHeight, getRowSpacing, applyRowHeight]);
|
|
300
285
|
const hydrateRowsMeta = React.useCallback(() => {
|
|
301
286
|
hasRowWithAutoHeight.current = false;
|
|
302
|
-
const pinnedTopRowsTotalHeight = pinnedRows
|
|
287
|
+
const pinnedTopRowsTotalHeight = pinnedRows?.top.reduce((acc, row) => {
|
|
303
288
|
const entry = processHeightEntry(row);
|
|
304
289
|
return acc + entry.content + entry.spacingTop + entry.spacingBottom + entry.detail;
|
|
305
|
-
}, 0);
|
|
306
|
-
const pinnedBottomRowsTotalHeight = pinnedRows
|
|
290
|
+
}, 0) ?? 0;
|
|
291
|
+
const pinnedBottomRowsTotalHeight = pinnedRows?.bottom.reduce((acc, row) => {
|
|
307
292
|
const entry = processHeightEntry(row);
|
|
308
293
|
return acc + entry.content + entry.spacingTop + entry.spacingBottom + entry.detail;
|
|
309
|
-
}, 0);
|
|
294
|
+
}, 0) ?? 0;
|
|
310
295
|
const positions = [];
|
|
311
296
|
const currentPageTotalHeight = rows.reduce((acc, row) => {
|
|
312
297
|
positions.push(acc);
|
|
@@ -362,7 +347,7 @@ function useRowsMeta(store, params, updateDimensions) {
|
|
|
362
347
|
const entry = entries[i];
|
|
363
348
|
const height = entry.borderBoxSize && entry.borderBoxSize.length > 0 ? entry.borderBoxSize[0].blockSize : entry.contentRect.height;
|
|
364
349
|
const rowId = entry.target.__mui_id;
|
|
365
|
-
const focusedVirtualRowId = params.focusedVirtualCell()?.id;
|
|
350
|
+
const focusedVirtualRowId = params.focusedVirtualCell?.()?.id;
|
|
366
351
|
if (focusedVirtualRowId === rowId && height === 0) {
|
|
367
352
|
// Focused virtual row has 0 height.
|
|
368
353
|
// We don't want to store it to avoid scroll jumping.
|
|
@@ -401,7 +386,7 @@ function useRowsMeta(store, params, updateDimensions) {
|
|
|
401
386
|
resetRowHeights
|
|
402
387
|
};
|
|
403
388
|
}
|
|
404
|
-
function observeRootNode(node, store) {
|
|
389
|
+
function observeRootNode(node, store, setRootSize) {
|
|
405
390
|
if (!node) {
|
|
406
391
|
return undefined;
|
|
407
392
|
}
|
|
@@ -411,9 +396,7 @@ function observeRootNode(node, store) {
|
|
|
411
396
|
height: roundToDecimalPlaces(bounds.height, 1)
|
|
412
397
|
};
|
|
413
398
|
if (store.state.rootSize === Size.EMPTY || !Size.equals(initialSize, store.state.rootSize)) {
|
|
414
|
-
|
|
415
|
-
rootSize: initialSize
|
|
416
|
-
});
|
|
399
|
+
setRootSize(initialSize);
|
|
417
400
|
}
|
|
418
401
|
if (typeof ResizeObserver === 'undefined') {
|
|
419
402
|
return undefined;
|
|
@@ -427,9 +410,7 @@ function observeRootNode(node, store) {
|
|
|
427
410
|
height: roundToDecimalPlaces(entry.contentRect.height, 1)
|
|
428
411
|
};
|
|
429
412
|
if (!Size.equals(rootSize, store.state.rootSize)) {
|
|
430
|
-
|
|
431
|
-
rootSize
|
|
432
|
-
});
|
|
413
|
+
setRootSize(rootSize);
|
|
433
414
|
}
|
|
434
415
|
});
|
|
435
416
|
observer.observe(node);
|
|
@@ -5,6 +5,16 @@ import type { CellColSpanInfo } from "../models/colspan.js";
|
|
|
5
5
|
import { Dimensions } from "./dimensions.js";
|
|
6
6
|
import type { BaseState, VirtualizerParams } from "../useVirtualizer.js";
|
|
7
7
|
import { PinnedRowPosition, RenderContext, ColumnsRenderContext, ColumnWithWidth, RowId, RowEntry } from "../models/index.js";
|
|
8
|
+
export type VirtualizationParams = {
|
|
9
|
+
/** @default false */
|
|
10
|
+
isRtl?: boolean;
|
|
11
|
+
/** The row buffer in pixels to render before and after the viewport.
|
|
12
|
+
* @default 150 */
|
|
13
|
+
rowBufferPx?: number;
|
|
14
|
+
/** The column buffer in pixels to render before and after the viewport.
|
|
15
|
+
* @default 150 */
|
|
16
|
+
columnBufferPx?: number;
|
|
17
|
+
};
|
|
8
18
|
export type VirtualizationState = {
|
|
9
19
|
enabled: boolean;
|
|
10
20
|
enabledForRows: boolean;
|
|
@@ -44,16 +54,16 @@ type RequiredAPI = Dimensions.API & AbstractAPI;
|
|
|
44
54
|
declare function useVirtualization(store: Store<BaseState>, params: VirtualizerParams, api: RequiredAPI): {
|
|
45
55
|
getters: {
|
|
46
56
|
setPanels: React.Dispatch<React.SetStateAction<Readonly<Map<any, React.ReactNode>>>>;
|
|
47
|
-
getRows: (rowParams
|
|
57
|
+
getRows: (rowParams?: {
|
|
48
58
|
rows?: RowEntry[];
|
|
49
59
|
position?: PinnedRowPosition;
|
|
50
60
|
renderContext?: RenderContext;
|
|
51
|
-
}
|
|
61
|
+
}, unstable_rowTree?: Record<RowId, any>) => React.ReactNode[];
|
|
52
62
|
getContainerProps: () => {
|
|
53
|
-
ref:
|
|
63
|
+
ref: (node: HTMLDivElement | null) => void;
|
|
54
64
|
};
|
|
55
65
|
getScrollerProps: () => {
|
|
56
|
-
ref:
|
|
66
|
+
ref: (node: HTMLDivElement | null) => void;
|
|
57
67
|
onScroll: () => void;
|
|
58
68
|
onWheel: ((event: React.WheelEvent) => void) | undefined;
|
|
59
69
|
onTouchMove: ((event: React.TouchEvent) => void) | undefined;
|
|
@@ -62,22 +72,19 @@ declare function useVirtualization(store: Store<BaseState>, params: VirtualizerP
|
|
|
62
72
|
tabIndex: number | undefined;
|
|
63
73
|
};
|
|
64
74
|
getContentProps: () => {
|
|
65
|
-
style: React.CSSProperties;
|
|
66
|
-
role: string;
|
|
67
75
|
ref: (node: HTMLDivElement | null) => void;
|
|
68
|
-
|
|
69
|
-
getRenderZoneProps: () => {
|
|
76
|
+
style: React.CSSProperties;
|
|
70
77
|
role: string;
|
|
71
78
|
};
|
|
72
79
|
getScrollbarVerticalProps: () => {
|
|
73
|
-
ref:
|
|
80
|
+
ref: (node: HTMLDivElement | null) => void;
|
|
74
81
|
scrollPosition: React.RefObject<{
|
|
75
82
|
top: number;
|
|
76
83
|
left: number;
|
|
77
84
|
}>;
|
|
78
85
|
};
|
|
79
86
|
getScrollbarHorizontalProps: () => {
|
|
80
|
-
ref:
|
|
87
|
+
ref: (node: HTMLDivElement | null) => void;
|
|
81
88
|
scrollPosition: React.RefObject<{
|
|
82
89
|
top: number;
|
|
83
90
|
left: number;
|