diff --git a/packages/component-base/src/virtualizer-iron-list-adapter.js b/packages/component-base/src/virtualizer-iron-list-adapter.js index 1ebe4c00ab..f1474c56a6 100644 --- a/packages/component-base/src/virtualizer-iron-list-adapter.js +++ b/packages/component-base/src/virtualizer-iron-list-adapter.js @@ -5,7 +5,7 @@ */ /* eslint-disable @typescript-eslint/member-ordering */ // https://github.com/vaadin/eslint-config-vaadin/issues/33 -import { animationFrame, timeOut } from './async.js'; +import { animationFrame, microTask, timeOut } from './async.js'; import { isSafari } from './browser-utils.js'; import { Debouncer, flush } from './debounce.js'; import { ironList } from './iron-list-core.js'; @@ -350,6 +350,9 @@ export class IronListAdapter { // Schedule and flush a resize handler this._resizeHandler(); flush(); + // Schedule an update to ensure item positions are correct after subsequent size changes + // Fix for https://github.com/vaadin/flow-components/issues/6269 + this._debounce('_update', this._update, microTask); } /** @private */ diff --git a/packages/component-base/test/virtualizer-variable-row-height.test.js b/packages/component-base/test/virtualizer-variable-row-height.test.js index 6d6146e41f..2fa7c1fbad 100644 --- a/packages/component-base/test/virtualizer-variable-row-height.test.js +++ b/packages/component-base/test/virtualizer-variable-row-height.test.js @@ -1,5 +1,5 @@ import { expect } from '@esm-bundle/chai'; -import { fixtureSync, nextFrame } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, isFirefox, nextFrame } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import { Virtualizer } from '../src/virtualizer.js'; @@ -204,7 +204,12 @@ describe('virtualizer - variable row height - large variance', () => { await fixItemPositioningTimeout(); const targetScrollTop = scrollTarget.scrollHeight - scrollTarget.offsetHeight; - expect(scrollTarget.scrollTop).to.equal(targetScrollTop); + if (isFirefox) { + // Firfox has a rounding issue that requires a small tolerance + expect(scrollTarget.scrollTop).to.be.closeTo(targetScrollTop, 1); + } else { + expect(scrollTarget.scrollTop).to.equal(targetScrollTop); + } }); it('should allow scrolling to start', async () => { @@ -233,3 +238,52 @@ describe('virtualizer - variable row height - large variance', () => { expect(virtualizer.__adapter.__fixInvalidItemPositioning.callCount).to.equal(0); }); }); + +describe('virtualizer - variable row height - size changes', () => { + let virtualizer; + + beforeEach(async () => { + const reverseItemHeights = [50, 30]; + + const scrollTarget = fixtureSync(` +