@angular/cdk-experimental 21.0.0-next.9 → 21.0.0-rc.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/fesm2022/_polyfill-chunk.mjs +8 -9
- package/fesm2022/_polyfill-chunk.mjs.map +1 -1
- package/fesm2022/cdk-experimental.mjs +1 -2
- package/fesm2022/cdk-experimental.mjs.map +1 -1
- package/fesm2022/column-resize.mjs +1115 -954
- package/fesm2022/column-resize.mjs.map +1 -1
- package/fesm2022/popover-edit.mjs +1125 -1061
- package/fesm2022/popover-edit.mjs.map +1 -1
- package/fesm2022/scrolling.mjs +292 -409
- package/fesm2022/scrolling.mjs.map +1 -1
- package/fesm2022/selection.mjs +698 -535
- package/fesm2022/selection.mjs.map +1 -1
- package/fesm2022/table-scroll-container.mjs +163 -113
- package/fesm2022/table-scroll-container.mjs.map +1 -1
- package/package.json +2 -2
package/fesm2022/scrolling.mjs
CHANGED
|
@@ -4,441 +4,324 @@ import * as i0 from '@angular/core';
|
|
|
4
4
|
import { forwardRef, Directive, Input, NgModule } from '@angular/core';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* A class that tracks the size of items that have been seen and uses it to estimate the average
|
|
9
|
-
* item size.
|
|
10
|
-
*/
|
|
11
7
|
class ItemSizeAverager {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* @param size The measured size of the given range in pixels.
|
|
31
|
-
*/
|
|
32
|
-
addSample(range, size) {
|
|
33
|
-
const newTotalWeight = this._totalWeight + range.end - range.start;
|
|
34
|
-
if (newTotalWeight) {
|
|
35
|
-
const newAverageItemSize = (size + this._averageItemSize * this._totalWeight) / newTotalWeight;
|
|
36
|
-
if (newAverageItemSize) {
|
|
37
|
-
this._averageItemSize = newAverageItemSize;
|
|
38
|
-
this._totalWeight = newTotalWeight;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/** Resets the averager. */
|
|
43
|
-
reset() {
|
|
44
|
-
this._averageItemSize = this._defaultItemSize;
|
|
45
|
-
this._totalWeight = 0;
|
|
8
|
+
_totalWeight = 0;
|
|
9
|
+
_averageItemSize;
|
|
10
|
+
_defaultItemSize;
|
|
11
|
+
constructor(defaultItemSize = 50) {
|
|
12
|
+
this._defaultItemSize = defaultItemSize;
|
|
13
|
+
this._averageItemSize = defaultItemSize;
|
|
14
|
+
}
|
|
15
|
+
getAverageItemSize() {
|
|
16
|
+
return this._averageItemSize;
|
|
17
|
+
}
|
|
18
|
+
addSample(range, size) {
|
|
19
|
+
const newTotalWeight = this._totalWeight + range.end - range.start;
|
|
20
|
+
if (newTotalWeight) {
|
|
21
|
+
const newAverageItemSize = (size + this._averageItemSize * this._totalWeight) / newTotalWeight;
|
|
22
|
+
if (newAverageItemSize) {
|
|
23
|
+
this._averageItemSize = newAverageItemSize;
|
|
24
|
+
this._totalWeight = newTotalWeight;
|
|
25
|
+
}
|
|
46
26
|
}
|
|
27
|
+
}
|
|
28
|
+
reset() {
|
|
29
|
+
this._averageItemSize = this._defaultItemSize;
|
|
30
|
+
this._totalWeight = 0;
|
|
31
|
+
}
|
|
47
32
|
}
|
|
48
|
-
/** Virtual scrolling strategy for lists with items of unknown or dynamic size. */
|
|
49
33
|
class AutoSizeVirtualScrollStrategy {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
54
|
-
throw Error('cdk-virtual-scroll: scrolledIndexChange is currently not supported for the' +
|
|
55
|
-
' autosize scroll strategy');
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
/** The attached viewport. */
|
|
59
|
-
_viewport = null;
|
|
60
|
-
/** The minimum amount of buffer rendered beyond the viewport (in pixels). */
|
|
61
|
-
_minBufferPx;
|
|
62
|
-
/** The number of buffer items to render beyond the edge of the viewport (in pixels). */
|
|
63
|
-
_maxBufferPx;
|
|
64
|
-
/** The estimator used to estimate the size of unseen items. */
|
|
65
|
-
_averager;
|
|
66
|
-
/** The last measured scroll offset of the viewport. */
|
|
67
|
-
_lastScrollOffset;
|
|
68
|
-
/** The last measured size of the rendered content in the viewport. */
|
|
69
|
-
_lastRenderedContentSize;
|
|
70
|
-
/** The last measured size of the rendered content in the viewport. */
|
|
71
|
-
_lastRenderedContentOffset;
|
|
72
|
-
/**
|
|
73
|
-
* The number of consecutive cycles where removing extra items has failed. Failure here means that
|
|
74
|
-
* we estimated how many items we could safely remove, but our estimate turned out to be too much
|
|
75
|
-
* and it wasn't safe to remove that many elements.
|
|
76
|
-
*/
|
|
77
|
-
_removalFailures = 0;
|
|
78
|
-
/**
|
|
79
|
-
* @param minBufferPx The minimum amount of buffer rendered beyond the viewport (in pixels).
|
|
80
|
-
* If the amount of buffer dips below this number, more items will be rendered.
|
|
81
|
-
* @param maxBufferPx The number of pixels worth of buffer to shoot for when rendering new items.
|
|
82
|
-
* If the actual amount turns out to be less it will not necessarily trigger an additional
|
|
83
|
-
* rendering cycle (as long as the amount of buffer is still greater than `minBufferPx`).
|
|
84
|
-
* @param averager The averager used to estimate the size of unseen items.
|
|
85
|
-
*/
|
|
86
|
-
constructor(minBufferPx, maxBufferPx, averager = new ItemSizeAverager()) {
|
|
87
|
-
this._minBufferPx = minBufferPx;
|
|
88
|
-
this._maxBufferPx = maxBufferPx;
|
|
89
|
-
this._averager = averager;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Attaches this scroll strategy to a viewport.
|
|
93
|
-
* @param viewport The viewport to attach this strategy to.
|
|
94
|
-
*/
|
|
95
|
-
attach(viewport) {
|
|
96
|
-
this._averager.reset();
|
|
97
|
-
this._viewport = viewport;
|
|
98
|
-
this._renderContentForCurrentOffset();
|
|
34
|
+
scrolledIndexChange = new Observable(() => {
|
|
35
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
36
|
+
throw Error('cdk-virtual-scroll: scrolledIndexChange is currently not supported for the' + ' autosize scroll strategy');
|
|
99
37
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
38
|
+
});
|
|
39
|
+
_viewport = null;
|
|
40
|
+
_minBufferPx;
|
|
41
|
+
_maxBufferPx;
|
|
42
|
+
_averager;
|
|
43
|
+
_lastScrollOffset;
|
|
44
|
+
_lastRenderedContentSize;
|
|
45
|
+
_lastRenderedContentOffset;
|
|
46
|
+
_removalFailures = 0;
|
|
47
|
+
constructor(minBufferPx, maxBufferPx, averager = new ItemSizeAverager()) {
|
|
48
|
+
this._minBufferPx = minBufferPx;
|
|
49
|
+
this._maxBufferPx = maxBufferPx;
|
|
50
|
+
this._averager = averager;
|
|
51
|
+
}
|
|
52
|
+
attach(viewport) {
|
|
53
|
+
this._averager.reset();
|
|
54
|
+
this._viewport = viewport;
|
|
55
|
+
this._renderContentForCurrentOffset();
|
|
56
|
+
}
|
|
57
|
+
detach() {
|
|
58
|
+
this._viewport = null;
|
|
59
|
+
}
|
|
60
|
+
onContentScrolled() {
|
|
61
|
+
if (this._viewport) {
|
|
62
|
+
this._updateRenderedContentAfterScroll();
|
|
103
63
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
64
|
+
}
|
|
65
|
+
onDataLengthChanged() {
|
|
66
|
+
if (this._viewport) {
|
|
67
|
+
this._renderContentForCurrentOffset();
|
|
68
|
+
this._checkRenderedContentSize();
|
|
109
69
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
this._checkRenderedContentSize();
|
|
115
|
-
}
|
|
70
|
+
}
|
|
71
|
+
onContentRendered() {
|
|
72
|
+
if (this._viewport) {
|
|
73
|
+
this._checkRenderedContentSize();
|
|
116
74
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
75
|
+
}
|
|
76
|
+
onRenderedOffsetChanged() {
|
|
77
|
+
if (this._viewport) {
|
|
78
|
+
this._checkRenderedContentOffset();
|
|
122
79
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
80
|
+
}
|
|
81
|
+
scrollToIndex() {
|
|
82
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
83
|
+
throw Error('cdk-virtual-scroll: scrollToIndex is currently not supported for the autosize' + ' scroll strategy');
|
|
128
84
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
throw Error('cdk-virtual-scroll: scrollToIndex is currently not supported for the autosize' +
|
|
134
|
-
' scroll strategy');
|
|
135
|
-
}
|
|
85
|
+
}
|
|
86
|
+
updateBufferSize(minBufferPx, maxBufferPx) {
|
|
87
|
+
if (maxBufferPx < minBufferPx) {
|
|
88
|
+
throw Error('CDK virtual scroll: maxBufferPx must be greater than or equal to minBufferPx');
|
|
136
89
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
90
|
+
this._minBufferPx = minBufferPx;
|
|
91
|
+
this._maxBufferPx = maxBufferPx;
|
|
92
|
+
}
|
|
93
|
+
_updateRenderedContentAfterScroll() {
|
|
94
|
+
const viewport = this._viewport;
|
|
95
|
+
const scrollOffset = viewport.measureScrollOffset();
|
|
96
|
+
let scrollDelta = scrollOffset - this._lastScrollOffset;
|
|
97
|
+
let scrollMagnitude = Math.abs(scrollDelta);
|
|
98
|
+
const renderedRange = viewport.getRenderedRange();
|
|
99
|
+
let offsetCorrection = 0;
|
|
100
|
+
if (scrollDelta < 0) {
|
|
101
|
+
const predictedOffset = renderedRange.start * this._averager.getAverageItemSize();
|
|
102
|
+
const offsetDifference = predictedOffset - this._lastRenderedContentOffset;
|
|
103
|
+
offsetCorrection = Math.round(offsetDifference * Math.max(0, Math.min(1, scrollMagnitude / (scrollOffset + scrollMagnitude))));
|
|
104
|
+
scrollDelta = scrollDelta - offsetCorrection;
|
|
105
|
+
scrollMagnitude = Math.abs(scrollDelta);
|
|
149
106
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
// of content and the actual amount of scrollable space may differ. We address this by slowly
|
|
163
|
-
// correcting the difference on each scroll event.
|
|
164
|
-
let offsetCorrection = 0;
|
|
107
|
+
const startBuffer = this._lastScrollOffset - this._lastRenderedContentOffset;
|
|
108
|
+
const endBuffer = this._lastRenderedContentOffset + this._lastRenderedContentSize - (this._lastScrollOffset + viewport.getViewportSize());
|
|
109
|
+
const underscan = scrollMagnitude + this._minBufferPx - (scrollDelta < 0 ? startBuffer : endBuffer);
|
|
110
|
+
if (underscan > 0) {
|
|
111
|
+
if (scrollMagnitude >= viewport.getViewportSize()) {
|
|
112
|
+
this._renderContentForCurrentOffset();
|
|
113
|
+
} else {
|
|
114
|
+
const addItems = Math.max(0, Math.ceil((underscan - this._minBufferPx + this._maxBufferPx) / this._averager.getAverageItemSize()));
|
|
115
|
+
const overscan = (scrollDelta < 0 ? endBuffer : startBuffer) - this._minBufferPx + scrollMagnitude;
|
|
116
|
+
const unboundedRemoveItems = Math.floor(overscan / this._averager.getAverageItemSize() / (this._removalFailures + 1));
|
|
117
|
+
const removeItems = Math.min(renderedRange.end - renderedRange.start, Math.max(0, unboundedRemoveItems));
|
|
118
|
+
const range = this._expandRange(renderedRange, scrollDelta < 0 ? addItems : 0, scrollDelta > 0 ? addItems : 0);
|
|
165
119
|
if (scrollDelta < 0) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// the actual available space to scroll over. We need to reduce this to zero by the time the
|
|
170
|
-
// user scrolls to the top.
|
|
171
|
-
// - 0 indicates that the predicted size and available space are the same.
|
|
172
|
-
// - A negative number that the predicted size is smaller than the available space.
|
|
173
|
-
// - A positive number indicates the predicted size is larger than the available space
|
|
174
|
-
const offsetDifference = predictedOffset - this._lastRenderedContentOffset;
|
|
175
|
-
// The amount of difference to correct during this scroll event. We calculate this as a
|
|
176
|
-
// percentage of the total difference based on the percentage of the distance toward the top
|
|
177
|
-
// that the user scrolled.
|
|
178
|
-
offsetCorrection = Math.round(offsetDifference *
|
|
179
|
-
Math.max(0, Math.min(1, scrollMagnitude / (scrollOffset + scrollMagnitude))));
|
|
180
|
-
// Based on the offset correction above, we pretend that the scroll delta was bigger or
|
|
181
|
-
// smaller than it actually was, this way we can start to eliminate the difference.
|
|
182
|
-
scrollDelta = scrollDelta - offsetCorrection;
|
|
183
|
-
scrollMagnitude = Math.abs(scrollDelta);
|
|
120
|
+
range.end = Math.max(range.start + 1, range.end - removeItems);
|
|
121
|
+
} else {
|
|
122
|
+
range.start = Math.min(range.end - 1, range.start + removeItems);
|
|
184
123
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
// remove.
|
|
216
|
-
const unboundedRemoveItems = Math.floor(overscan / this._averager.getAverageItemSize() / (this._removalFailures + 1));
|
|
217
|
-
const removeItems = Math.min(renderedRange.end - renderedRange.start, Math.max(0, unboundedRemoveItems));
|
|
218
|
-
// The new range we will tell the viewport to render. We first expand it to include the new
|
|
219
|
-
// items we want rendered, we then contract the opposite side to remove items we no longer
|
|
220
|
-
// want rendered.
|
|
221
|
-
const range = this._expandRange(renderedRange, scrollDelta < 0 ? addItems : 0, scrollDelta > 0 ? addItems : 0);
|
|
222
|
-
if (scrollDelta < 0) {
|
|
223
|
-
range.end = Math.max(range.start + 1, range.end - removeItems);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
range.start = Math.min(range.end - 1, range.start + removeItems);
|
|
227
|
-
}
|
|
228
|
-
// The new offset we want to set on the rendered content. To determine this we measure the
|
|
229
|
-
// number of pixels we removed and then adjust the offset to the start of the rendered
|
|
230
|
-
// content or to the end of the rendered content accordingly (whichever one doesn't require
|
|
231
|
-
// that the newly added items to be rendered to calculate.)
|
|
232
|
-
let contentOffset;
|
|
233
|
-
let contentOffsetTo;
|
|
234
|
-
if (scrollDelta < 0) {
|
|
235
|
-
let removedSize = viewport.measureRangeSize({
|
|
236
|
-
start: range.end,
|
|
237
|
-
end: renderedRange.end,
|
|
238
|
-
});
|
|
239
|
-
// Check that we're not removing too much.
|
|
240
|
-
if (removedSize <= overscan) {
|
|
241
|
-
contentOffset =
|
|
242
|
-
this._lastRenderedContentOffset + this._lastRenderedContentSize - removedSize;
|
|
243
|
-
this._removalFailures = 0;
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
// If the removal is more than the overscan can absorb just undo it and record the fact
|
|
247
|
-
// that the removal failed so we can be less aggressive next time.
|
|
248
|
-
range.end = renderedRange.end;
|
|
249
|
-
contentOffset = this._lastRenderedContentOffset + this._lastRenderedContentSize;
|
|
250
|
-
this._removalFailures++;
|
|
251
|
-
}
|
|
252
|
-
contentOffsetTo = 'to-end';
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
const removedSize = viewport.measureRangeSize({
|
|
256
|
-
start: renderedRange.start,
|
|
257
|
-
end: range.start,
|
|
258
|
-
});
|
|
259
|
-
// Check that we're not removing too much.
|
|
260
|
-
if (removedSize <= overscan) {
|
|
261
|
-
contentOffset = this._lastRenderedContentOffset + removedSize;
|
|
262
|
-
this._removalFailures = 0;
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
// If the removal is more than the overscan can absorb just undo it and record the fact
|
|
266
|
-
// that the removal failed so we can be less aggressive next time.
|
|
267
|
-
range.start = renderedRange.start;
|
|
268
|
-
contentOffset = this._lastRenderedContentOffset;
|
|
269
|
-
this._removalFailures++;
|
|
270
|
-
}
|
|
271
|
-
contentOffsetTo = 'to-start';
|
|
272
|
-
}
|
|
273
|
-
// Set the range and offset we calculated above.
|
|
274
|
-
viewport.setRenderedRange(range);
|
|
275
|
-
viewport.setRenderedContentOffset(contentOffset + offsetCorrection, contentOffsetTo);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
else if (offsetCorrection) {
|
|
279
|
-
// Even if the rendered range didn't change, we may still need to adjust the content offset to
|
|
280
|
-
// simulate scrolling slightly slower or faster than the user actually scrolled.
|
|
281
|
-
viewport.setRenderedContentOffset(this._lastRenderedContentOffset + offsetCorrection);
|
|
124
|
+
let contentOffset;
|
|
125
|
+
let contentOffsetTo;
|
|
126
|
+
if (scrollDelta < 0) {
|
|
127
|
+
let removedSize = viewport.measureRangeSize({
|
|
128
|
+
start: range.end,
|
|
129
|
+
end: renderedRange.end
|
|
130
|
+
});
|
|
131
|
+
if (removedSize <= overscan) {
|
|
132
|
+
contentOffset = this._lastRenderedContentOffset + this._lastRenderedContentSize - removedSize;
|
|
133
|
+
this._removalFailures = 0;
|
|
134
|
+
} else {
|
|
135
|
+
range.end = renderedRange.end;
|
|
136
|
+
contentOffset = this._lastRenderedContentOffset + this._lastRenderedContentSize;
|
|
137
|
+
this._removalFailures++;
|
|
138
|
+
}
|
|
139
|
+
contentOffsetTo = 'to-end';
|
|
140
|
+
} else {
|
|
141
|
+
const removedSize = viewport.measureRangeSize({
|
|
142
|
+
start: renderedRange.start,
|
|
143
|
+
end: range.start
|
|
144
|
+
});
|
|
145
|
+
if (removedSize <= overscan) {
|
|
146
|
+
contentOffset = this._lastRenderedContentOffset + removedSize;
|
|
147
|
+
this._removalFailures = 0;
|
|
148
|
+
} else {
|
|
149
|
+
range.start = renderedRange.start;
|
|
150
|
+
contentOffset = this._lastRenderedContentOffset;
|
|
151
|
+
this._removalFailures++;
|
|
152
|
+
}
|
|
153
|
+
contentOffsetTo = 'to-start';
|
|
282
154
|
}
|
|
283
|
-
// Save the scroll offset to be compared to the new value on the next scroll event.
|
|
284
|
-
this._lastScrollOffset = scrollOffset;
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Checks the size of the currently rendered content and uses it to update the estimated item size
|
|
288
|
-
* and estimated total content size.
|
|
289
|
-
*/
|
|
290
|
-
_checkRenderedContentSize() {
|
|
291
|
-
const viewport = this._viewport;
|
|
292
|
-
this._lastRenderedContentSize = viewport.measureRenderedContentSize();
|
|
293
|
-
this._averager.addSample(viewport.getRenderedRange(), this._lastRenderedContentSize);
|
|
294
|
-
this._updateTotalContentSize(this._lastRenderedContentSize);
|
|
295
|
-
}
|
|
296
|
-
/** Checks the currently rendered content offset and saves the value for later use. */
|
|
297
|
-
_checkRenderedContentOffset() {
|
|
298
|
-
const viewport = this._viewport;
|
|
299
|
-
this._lastRenderedContentOffset = viewport.getOffsetToRenderedContentStart();
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Recalculates the rendered content based on our estimate of what should be shown at the current
|
|
303
|
-
* scroll offset.
|
|
304
|
-
*/
|
|
305
|
-
_renderContentForCurrentOffset() {
|
|
306
|
-
const viewport = this._viewport;
|
|
307
|
-
const scrollOffset = viewport.measureScrollOffset();
|
|
308
|
-
this._lastScrollOffset = scrollOffset;
|
|
309
|
-
this._removalFailures = 0;
|
|
310
|
-
const itemSize = this._averager.getAverageItemSize();
|
|
311
|
-
const firstVisibleIndex = Math.min(viewport.getDataLength() - 1, Math.floor(scrollOffset / itemSize));
|
|
312
|
-
const bufferSize = Math.ceil(this._maxBufferPx / itemSize);
|
|
313
|
-
const range = this._expandRange(this._getVisibleRangeForIndex(firstVisibleIndex), bufferSize, bufferSize);
|
|
314
155
|
viewport.setRenderedRange(range);
|
|
315
|
-
viewport.setRenderedContentOffset(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
* Gets the visible range of data for the given start index. If the start index is too close to
|
|
320
|
-
* the end of the list it may be backed up to ensure the estimated size of the range is enough to
|
|
321
|
-
* fill the viewport.
|
|
322
|
-
* Note: must not be called if `this._viewport` is null
|
|
323
|
-
* @param startIndex The index to start the range at
|
|
324
|
-
* @return a range estimated to be large enough to fill the viewport when rendered.
|
|
325
|
-
*/
|
|
326
|
-
_getVisibleRangeForIndex(startIndex) {
|
|
327
|
-
const viewport = this._viewport;
|
|
328
|
-
const range = {
|
|
329
|
-
start: startIndex,
|
|
330
|
-
end: startIndex + Math.ceil(viewport.getViewportSize() / this._averager.getAverageItemSize()),
|
|
331
|
-
};
|
|
332
|
-
const extra = range.end - viewport.getDataLength();
|
|
333
|
-
if (extra > 0) {
|
|
334
|
-
range.start = Math.max(0, range.start - extra);
|
|
335
|
-
}
|
|
336
|
-
return range;
|
|
156
|
+
viewport.setRenderedContentOffset(contentOffset + offsetCorrection, contentOffsetTo);
|
|
157
|
+
}
|
|
158
|
+
} else if (offsetCorrection) {
|
|
159
|
+
viewport.setRenderedContentOffset(this._lastRenderedContentOffset + offsetCorrection);
|
|
337
160
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
161
|
+
this._lastScrollOffset = scrollOffset;
|
|
162
|
+
}
|
|
163
|
+
_checkRenderedContentSize() {
|
|
164
|
+
const viewport = this._viewport;
|
|
165
|
+
this._lastRenderedContentSize = viewport.measureRenderedContentSize();
|
|
166
|
+
this._averager.addSample(viewport.getRenderedRange(), this._lastRenderedContentSize);
|
|
167
|
+
this._updateTotalContentSize(this._lastRenderedContentSize);
|
|
168
|
+
}
|
|
169
|
+
_checkRenderedContentOffset() {
|
|
170
|
+
const viewport = this._viewport;
|
|
171
|
+
this._lastRenderedContentOffset = viewport.getOffsetToRenderedContentStart();
|
|
172
|
+
}
|
|
173
|
+
_renderContentForCurrentOffset() {
|
|
174
|
+
const viewport = this._viewport;
|
|
175
|
+
const scrollOffset = viewport.measureScrollOffset();
|
|
176
|
+
this._lastScrollOffset = scrollOffset;
|
|
177
|
+
this._removalFailures = 0;
|
|
178
|
+
const itemSize = this._averager.getAverageItemSize();
|
|
179
|
+
const firstVisibleIndex = Math.min(viewport.getDataLength() - 1, Math.floor(scrollOffset / itemSize));
|
|
180
|
+
const bufferSize = Math.ceil(this._maxBufferPx / itemSize);
|
|
181
|
+
const range = this._expandRange(this._getVisibleRangeForIndex(firstVisibleIndex), bufferSize, bufferSize);
|
|
182
|
+
viewport.setRenderedRange(range);
|
|
183
|
+
viewport.setRenderedContentOffset(itemSize * range.start);
|
|
184
|
+
}
|
|
185
|
+
_getVisibleRangeForIndex(startIndex) {
|
|
186
|
+
const viewport = this._viewport;
|
|
187
|
+
const range = {
|
|
188
|
+
start: startIndex,
|
|
189
|
+
end: startIndex + Math.ceil(viewport.getViewportSize() / this._averager.getAverageItemSize())
|
|
190
|
+
};
|
|
191
|
+
const extra = range.end - viewport.getDataLength();
|
|
192
|
+
if (extra > 0) {
|
|
193
|
+
range.start = Math.max(0, range.start - extra);
|
|
361
194
|
}
|
|
195
|
+
return range;
|
|
196
|
+
}
|
|
197
|
+
_expandRange(range, expandStart, expandEnd) {
|
|
198
|
+
const viewport = this._viewport;
|
|
199
|
+
const start = Math.max(0, range.start - expandStart);
|
|
200
|
+
const end = Math.min(viewport.getDataLength(), range.end + expandEnd);
|
|
201
|
+
return {
|
|
202
|
+
start,
|
|
203
|
+
end
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
_updateTotalContentSize(renderedContentSize) {
|
|
207
|
+
const viewport = this._viewport;
|
|
208
|
+
const renderedRange = viewport.getRenderedRange();
|
|
209
|
+
const totalSize = renderedContentSize + (viewport.getDataLength() - (renderedRange.end - renderedRange.start)) * this._averager.getAverageItemSize();
|
|
210
|
+
viewport.setTotalContentSize(totalSize);
|
|
211
|
+
}
|
|
362
212
|
}
|
|
363
|
-
/**
|
|
364
|
-
* Provider factory for `AutoSizeVirtualScrollStrategy` that simply extracts the already created
|
|
365
|
-
* `AutoSizeVirtualScrollStrategy` from the given directive.
|
|
366
|
-
* @param autoSizeDir The instance of `CdkAutoSizeVirtualScroll` to extract the
|
|
367
|
-
* `AutoSizeVirtualScrollStrategy` from.
|
|
368
|
-
*/
|
|
369
213
|
function _autoSizeVirtualScrollStrategyFactory(autoSizeDir) {
|
|
370
|
-
|
|
214
|
+
return autoSizeDir._scrollStrategy;
|
|
371
215
|
}
|
|
372
|
-
/** A virtual scroll strategy that supports unknown or dynamic size items. */
|
|
373
216
|
class CdkAutoSizeVirtualScroll {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
217
|
+
get minBufferPx() {
|
|
218
|
+
return this._minBufferPx;
|
|
219
|
+
}
|
|
220
|
+
set minBufferPx(value) {
|
|
221
|
+
this._minBufferPx = coerceNumberProperty(value);
|
|
222
|
+
}
|
|
223
|
+
_minBufferPx = 100;
|
|
224
|
+
get maxBufferPx() {
|
|
225
|
+
return this._maxBufferPx;
|
|
226
|
+
}
|
|
227
|
+
set maxBufferPx(value) {
|
|
228
|
+
this._maxBufferPx = coerceNumberProperty(value);
|
|
229
|
+
}
|
|
230
|
+
_maxBufferPx = 200;
|
|
231
|
+
_scrollStrategy = new AutoSizeVirtualScrollStrategy(this.minBufferPx, this.maxBufferPx);
|
|
232
|
+
ngOnChanges() {
|
|
233
|
+
this._scrollStrategy.updateBufferSize(this.minBufferPx, this.maxBufferPx);
|
|
234
|
+
}
|
|
235
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
236
|
+
minVersion: "12.0.0",
|
|
237
|
+
version: "20.2.0-next.2",
|
|
238
|
+
ngImport: i0,
|
|
239
|
+
type: CdkAutoSizeVirtualScroll,
|
|
240
|
+
deps: [],
|
|
241
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
242
|
+
});
|
|
243
|
+
static ɵdir = i0.ɵɵngDeclareDirective({
|
|
244
|
+
minVersion: "14.0.0",
|
|
245
|
+
version: "20.2.0-next.2",
|
|
246
|
+
type: CdkAutoSizeVirtualScroll,
|
|
247
|
+
isStandalone: true,
|
|
248
|
+
selector: "cdk-virtual-scroll-viewport[autosize]",
|
|
249
|
+
inputs: {
|
|
250
|
+
minBufferPx: "minBufferPx",
|
|
251
|
+
maxBufferPx: "maxBufferPx"
|
|
252
|
+
},
|
|
253
|
+
providers: [{
|
|
254
|
+
provide: VIRTUAL_SCROLL_STRATEGY,
|
|
255
|
+
useFactory: _autoSizeVirtualScrollStrategyFactory,
|
|
256
|
+
deps: [forwardRef(() => CdkAutoSizeVirtualScroll)]
|
|
257
|
+
}],
|
|
258
|
+
usesOnChanges: true,
|
|
259
|
+
ngImport: i0
|
|
260
|
+
});
|
|
411
261
|
}
|
|
412
|
-
i0.ɵɵngDeclareClassMetadata({
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
262
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
263
|
+
minVersion: "12.0.0",
|
|
264
|
+
version: "20.2.0-next.2",
|
|
265
|
+
ngImport: i0,
|
|
266
|
+
type: CdkAutoSizeVirtualScroll,
|
|
267
|
+
decorators: [{
|
|
268
|
+
type: Directive,
|
|
269
|
+
args: [{
|
|
270
|
+
selector: 'cdk-virtual-scroll-viewport[autosize]',
|
|
271
|
+
providers: [{
|
|
272
|
+
provide: VIRTUAL_SCROLL_STRATEGY,
|
|
273
|
+
useFactory: _autoSizeVirtualScrollStrategyFactory,
|
|
274
|
+
deps: [forwardRef(() => CdkAutoSizeVirtualScroll)]
|
|
275
|
+
}]
|
|
276
|
+
}]
|
|
277
|
+
}],
|
|
278
|
+
propDecorators: {
|
|
279
|
+
minBufferPx: [{
|
|
280
|
+
type: Input
|
|
281
|
+
}],
|
|
282
|
+
maxBufferPx: [{
|
|
283
|
+
type: Input
|
|
284
|
+
}]
|
|
285
|
+
}
|
|
286
|
+
});
|
|
429
287
|
|
|
430
288
|
class ScrollingModule {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
289
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
290
|
+
minVersion: "12.0.0",
|
|
291
|
+
version: "20.2.0-next.2",
|
|
292
|
+
ngImport: i0,
|
|
293
|
+
type: ScrollingModule,
|
|
294
|
+
deps: [],
|
|
295
|
+
target: i0.ɵɵFactoryTarget.NgModule
|
|
296
|
+
});
|
|
297
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({
|
|
298
|
+
minVersion: "14.0.0",
|
|
299
|
+
version: "20.2.0-next.2",
|
|
300
|
+
ngImport: i0,
|
|
301
|
+
type: ScrollingModule,
|
|
302
|
+
imports: [CdkAutoSizeVirtualScroll],
|
|
303
|
+
exports: [CdkAutoSizeVirtualScroll]
|
|
304
|
+
});
|
|
305
|
+
static ɵinj = i0.ɵɵngDeclareInjector({
|
|
306
|
+
minVersion: "12.0.0",
|
|
307
|
+
version: "20.2.0-next.2",
|
|
308
|
+
ngImport: i0,
|
|
309
|
+
type: ScrollingModule
|
|
310
|
+
});
|
|
434
311
|
}
|
|
435
|
-
i0.ɵɵngDeclareClassMetadata({
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
312
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
313
|
+
minVersion: "12.0.0",
|
|
314
|
+
version: "20.2.0-next.2",
|
|
315
|
+
ngImport: i0,
|
|
316
|
+
type: ScrollingModule,
|
|
317
|
+
decorators: [{
|
|
318
|
+
type: NgModule,
|
|
319
|
+
args: [{
|
|
320
|
+
imports: [CdkAutoSizeVirtualScroll],
|
|
321
|
+
exports: [CdkAutoSizeVirtualScroll]
|
|
322
|
+
}]
|
|
323
|
+
}]
|
|
324
|
+
});
|
|
442
325
|
|
|
443
326
|
export { AutoSizeVirtualScrollStrategy, CdkAutoSizeVirtualScroll, ItemSizeAverager, ScrollingModule, _autoSizeVirtualScrollStrategyFactory };
|
|
444
327
|
//# sourceMappingURL=scrolling.mjs.map
|