Skip to content

Commit f6bcbb1

Browse files
authored
fix(cdk/scrolling): content jumping in appendOnly mode (#25097)
We were creating the `transform` string before adjusting the offset for `appendOnly` mode which was causing the list to jump down before being reset on the next scroll event. These changes resolve the issue by moving the offset adjustment up to before the `transform`. Fixes #25077.
1 parent 3278214 commit f6bcbb1

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

src/cdk/scrolling/virtual-scroll-viewport.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,7 @@ describe('CdkVirtualScrollViewport', () => {
10301030
let fixture: ComponentFixture<VirtualScrollWithAppendOnly>;
10311031
let testComponent: VirtualScrollWithAppendOnly;
10321032
let viewport: CdkVirtualScrollViewport;
1033+
let contentWrapperEl: HTMLElement;
10331034

10341035
beforeEach(waitForAsync(() => {
10351036
TestBed.configureTestingModule({
@@ -1039,6 +1040,9 @@ describe('CdkVirtualScrollViewport', () => {
10391040
fixture = TestBed.createComponent(VirtualScrollWithAppendOnly);
10401041
testComponent = fixture.componentInstance;
10411042
viewport = testComponent.viewport;
1043+
contentWrapperEl = fixture.nativeElement.querySelector(
1044+
'.cdk-virtual-scroll-content-wrapper',
1045+
) as HTMLElement;
10421046
}));
10431047

10441048
it('should not remove item that have already been rendered', fakeAsync(() => {
@@ -1085,6 +1089,21 @@ describe('CdkVirtualScrollViewport', () => {
10851089

10861090
expect(viewport.getOffsetToRenderedContentStart()).toBe(0);
10871091
}));
1092+
1093+
it('should not set a transform when scrolling', fakeAsync(() => {
1094+
finishInit(fixture);
1095+
triggerScroll(viewport, 0);
1096+
fixture.detectChanges();
1097+
flush();
1098+
1099+
expect(contentWrapperEl.style.transform).toBe('translateY(0px)');
1100+
1101+
triggerScroll(viewport, testComponent.itemSize * 10);
1102+
fixture.detectChanges();
1103+
flush();
1104+
1105+
expect(contentWrapperEl.style.transform).toBe('translateY(0px)');
1106+
}));
10881107
});
10891108

10901109
describe('with custom scrolling element', () => {

src/cdk/scrolling/virtual-scroll-viewport.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,15 +333,16 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
333333
* (in pixels).
334334
*/
335335
setRenderedContentOffset(offset: number, to: 'to-start' | 'to-end' = 'to-start') {
336+
// In appendOnly, we always start from the top
337+
offset = this.appendOnly && to === 'to-start' ? 0 : offset;
338+
336339
// For a horizontal viewport in a right-to-left language we need to translate along the x-axis
337340
// in the negative direction.
338341
const isRtl = this.dir && this.dir.value == 'rtl';
339342
const isHorizontal = this.orientation == 'horizontal';
340343
const axis = isHorizontal ? 'X' : 'Y';
341344
const axisDirection = isHorizontal && isRtl ? -1 : 1;
342345
let transform = `translate${axis}(${Number(axisDirection * offset)}px)`;
343-
// in appendOnly, we always start from the top
344-
offset = this.appendOnly && to === 'to-start' ? 0 : offset;
345346
this._renderedContentOffset = offset;
346347
if (to === 'to-end') {
347348
transform += ` translate${axis}(-100%)`;

0 commit comments

Comments
 (0)