Skip to content

Commit

Permalink
fix(cdk/scrolling): content jumping in appendOnly mode (#25097)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
crisbeto authored Jun 18, 2022
1 parent 3278214 commit f6bcbb1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
19 changes: 19 additions & 0 deletions src/cdk/scrolling/virtual-scroll-viewport.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,7 @@ describe('CdkVirtualScrollViewport', () => {
let fixture: ComponentFixture<VirtualScrollWithAppendOnly>;
let testComponent: VirtualScrollWithAppendOnly;
let viewport: CdkVirtualScrollViewport;
let contentWrapperEl: HTMLElement;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
Expand All @@ -1039,6 +1040,9 @@ describe('CdkVirtualScrollViewport', () => {
fixture = TestBed.createComponent(VirtualScrollWithAppendOnly);
testComponent = fixture.componentInstance;
viewport = testComponent.viewport;
contentWrapperEl = fixture.nativeElement.querySelector(
'.cdk-virtual-scroll-content-wrapper',
) as HTMLElement;
}));

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

expect(viewport.getOffsetToRenderedContentStart()).toBe(0);
}));

it('should not set a transform when scrolling', fakeAsync(() => {
finishInit(fixture);
triggerScroll(viewport, 0);
fixture.detectChanges();
flush();

expect(contentWrapperEl.style.transform).toBe('translateY(0px)');

triggerScroll(viewport, testComponent.itemSize * 10);
fixture.detectChanges();
flush();

expect(contentWrapperEl.style.transform).toBe('translateY(0px)');
}));
});

describe('with custom scrolling element', () => {
Expand Down
5 changes: 3 additions & 2 deletions src/cdk/scrolling/virtual-scroll-viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,15 +333,16 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
* (in pixels).
*/
setRenderedContentOffset(offset: number, to: 'to-start' | 'to-end' = 'to-start') {
// In appendOnly, we always start from the top
offset = this.appendOnly && to === 'to-start' ? 0 : offset;

// For a horizontal viewport in a right-to-left language we need to translate along the x-axis
// in the negative direction.
const isRtl = this.dir && this.dir.value == 'rtl';
const isHorizontal = this.orientation == 'horizontal';
const axis = isHorizontal ? 'X' : 'Y';
const axisDirection = isHorizontal && isRtl ? -1 : 1;
let transform = `translate${axis}(${Number(axisDirection * offset)}px)`;
// in appendOnly, we always start from the top
offset = this.appendOnly && to === 'to-start' ? 0 : offset;
this._renderedContentOffset = offset;
if (to === 'to-end') {
transform += ` translate${axis}(-100%)`;
Expand Down

0 comments on commit f6bcbb1

Please sign in to comment.