diff --git a/packages/form-layout/src/vaadin-form-layout.js b/packages/form-layout/src/vaadin-form-layout.js index 7c6ce221b5..34a0e7f501 100644 --- a/packages/form-layout/src/vaadin-form-layout.js +++ b/packages/form-layout/src/vaadin-form-layout.js @@ -240,6 +240,11 @@ class FormLayout extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)) _labelsOnTop: { type: Boolean, }, + + /** @private */ + __isVisible: { + type: Boolean, + }, }; } @@ -264,6 +269,22 @@ class FormLayout extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)) this.addEventListener('animationend', this.__onAnimationEnd); } + constructor() { + super(); + + this.__intersectionObserver = new IntersectionObserver(([entry]) => { + if (!entry.isIntersecting) { + // Prevent possible jump when layout becomes visible + this.$.layout.style.opacity = 0; + } + if (!this.__isVisible && entry.isIntersecting) { + this._updateLayout(); + this.$.layout.style.opacity = ''; + } + this.__isVisible = entry.isIntersecting; + }); + } + /** @protected */ connectedCallback() { super.connectedCallback(); @@ -272,6 +293,7 @@ class FormLayout extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)) requestAnimationFrame(() => this._updateLayout()); this._observeChildrenColspanChange(); + this.__intersectionObserver.observe(this); } /** @protected */ @@ -280,6 +302,7 @@ class FormLayout extends ResizeMixin(ElementMixin(ThemableMixin(PolymerElement)) this.__mutationObserver.disconnect(); this.__childObserver.disconnect(); + this.__intersectionObserver.disconnect(); } /** @private */ diff --git a/packages/form-layout/test/form-layout.test.js b/packages/form-layout/test/form-layout.test.js index fa51249108..33c39908c3 100644 --- a/packages/form-layout/test/form-layout.test.js +++ b/packages/form-layout/test/form-layout.test.js @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { aTimeout, fixtureSync, nextRender } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, nextFrame, nextRender } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import '@polymer/polymer/lib/elements/dom-repeat.js'; import '@vaadin/text-field/vaadin-text-field.js'; @@ -519,7 +519,10 @@ describe('form layout', () => { beforeEach(() => { container = fixtureSync(`