From 48a1ed3f9cd9bebd8d736d72a021f48f10115e38 Mon Sep 17 00:00:00 2001 From: Tomi Virkki Date: Fri, 17 Mar 2023 10:54:36 +0200 Subject: [PATCH] fix: use a delay in the app layout resize observer (#5575) --- packages/app-layout/src/vaadin-app-layout.js | 6 ++-- packages/app-layout/test/app-layout.test.js | 31 +++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/packages/app-layout/src/vaadin-app-layout.js b/packages/app-layout/src/vaadin-app-layout.js index 3d8c11e14b..d148b3b954 100644 --- a/packages/app-layout/src/vaadin-app-layout.js +++ b/packages/app-layout/src/vaadin-app-layout.js @@ -452,8 +452,10 @@ class AppLayout extends ElementMixin(ThemableMixin(ControllerMixin(PolymerElemen this._updateOverlayMode(); this._navbarSizeObserver = new ResizeObserver(() => { - this._blockAnimationUntilAfterNextRender(); - this._updateOffsetSize(); + requestAnimationFrame(() => { + this._blockAnimationUntilAfterNextRender(); + this._updateOffsetSize(); + }); }); this._navbarSizeObserver.observe(this.$.navbarTop); this._navbarSizeObserver.observe(this.$.navbarBottom); diff --git a/packages/app-layout/test/app-layout.test.js b/packages/app-layout/test/app-layout.test.js index 257951327d..501a05694e 100644 --- a/packages/app-layout/test/app-layout.test.js +++ b/packages/app-layout/test/app-layout.test.js @@ -12,6 +12,26 @@ import sinon from 'sinon'; import '../vaadin-app-layout.js'; import '../vaadin-drawer-toggle.js'; +/** + * Resolves once the function is invoked on the given object. + */ +function onceInvoked(object, functionName) { + return new Promise((resolve) => { + sinon.replace(object, functionName, (...args) => { + sinon.restore(); + object[functionName](...args); + resolve(); + }); + }); +} + +/** + * Resolves once the ResizeObserver has processed a resize. + */ +async function onceResized(layout) { + await onceInvoked(layout, '_updateOffsetSize'); +} + describe('vaadin-app-layout', () => { let layout; @@ -90,12 +110,12 @@ describe('vaadin-app-layout', () => { navbarContent.style.height = '50px'; navbarContent.setAttribute('slot', 'navbar'); layout.appendChild(navbarContent); - await nextFrame(); + await onceResized(layout); const initialOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-top')); expect(initialOffset).to.be.greaterThan(0); // Increase navbar content size and measure increase navbarContent.style.height = '100px'; - await nextFrame(); + await onceResized(layout); const updatedOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-top')); expect(updatedOffset).to.equal(initialOffset + 50); }); @@ -134,12 +154,12 @@ describe('vaadin-app-layout', () => { navbarContent.style.height = '50px'; navbarContent.setAttribute('slot', 'navbar touch-optimized'); layout.appendChild(navbarContent); - await nextFrame(); + await onceResized(layout); const initialOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-bottom')); expect(initialOffset).to.be.greaterThan(0); // Increase navbar content size and measure increase navbarContent.style.height = '100px'; - await nextFrame(); + await onceResized(layout); const updatedOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-bottom')); expect(updatedOffset).to.equal(initialOffset + 50); }); @@ -167,6 +187,9 @@ describe('vaadin-app-layout', () => { toggle = layout.querySelector('#toggle'); drawer = layout.shadowRoot.querySelector('[part=drawer]'); backdrop = layout.shadowRoot.querySelector('[part=backdrop]'); + // Wait for the initial resize observer callback + await onceResized(layout); + await nextFrame(); } describe('desktop layout', () => {