Skip to content

Commit 2ad1677

Browse files
committed
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. (cherry picked from commit f6bcbb1)
1 parent ae3b4d6 commit 2ad1677

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

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,16 @@ export class CdkVirtualScrollViewport extends CdkScrollable implements OnInit, O
314314
* (in pixels).
315315
*/
316316
setRenderedContentOffset(offset: number, to: 'to-start' | 'to-end' = 'to-start') {
317+
// In appendOnly, we always start from the top
318+
offset = this.appendOnly && to === 'to-start' ? 0 : offset;
319+
317320
// For a horizontal viewport in a right-to-left language we need to translate along the x-axis
318321
// in the negative direction.
319322
const isRtl = this.dir && this.dir.value == 'rtl';
320323
const isHorizontal = this.orientation == 'horizontal';
321324
const axis = isHorizontal ? 'X' : 'Y';
322325
const axisDirection = isHorizontal && isRtl ? -1 : 1;
323326
let transform = `translate${axis}(${Number(axisDirection * offset)}px)`;
324-
// in appendOnly, we always start from the top
325-
offset = this.appendOnly && to === 'to-start' ? 0 : offset;
326327
this._renderedContentOffset = offset;
327328
if (to === 'to-end') {
328329
transform += ` translate${axis}(-100%)`;

0 commit comments

Comments
 (0)