diff --git a/packages/component-base/src/polylit-mixin.js b/packages/component-base/src/polylit-mixin.js index e6ea4a233f..0df8ca5abc 100644 --- a/packages/component-base/src/polylit-mixin.js +++ b/packages/component-base/src/polylit-mixin.js @@ -213,6 +213,9 @@ const PolylitMixinImplementation = (superclass) => { /** @protected */ updated(props) { + const wasReadyInvoked = this.__isReadyInvoked; + this.__isReadyInvoked = true; + if (this.constructor.__observers) { this.__runObservers(props, this.constructor.__observers); } @@ -233,8 +236,7 @@ const PolylitMixinImplementation = (superclass) => { this.__runNotifyProps(props, this.constructor.__notifyProps); } - if (!this.__isReadyInvoked) { - this.__isReadyInvoked = true; + if (!wasReadyInvoked) { this.ready(); } } diff --git a/packages/component-base/test/polylit-mixin.test.js b/packages/component-base/test/polylit-mixin.test.js index f2d47bbe46..0f243e7b85 100644 --- a/packages/component-base/test/polylit-mixin.test.js +++ b/packages/component-base/test/polylit-mixin.test.js @@ -1069,6 +1069,79 @@ describe('PolylitMixin', () => { }); }); + describe('sync observers', () => { + let element; + const readySpy = sinon.spy(); + const openedChangedSpy = sinon.spy(); + const headerChangedSpy = sinon.spy(); + const contentChangedSpy = sinon.spy(); + + const tag = defineCE( + class extends PolylitMixin(LitElement) { + static get properties() { + return { + opened: { + type: Boolean, + sync: true, + }, + + header: { + type: String, + sync: true, + }, + + content: { + type: String, + sync: true, + }, + }; + } + + static get observers() { + return ['openedChanged(opened)', 'headerChanged(opened, header)', 'contentChanged(opened, content)']; + } + + ready() { + super.ready(); + readySpy(); + } + + openedChanged(opened) { + openedChangedSpy(); + + if (opened) { + this.header = 'Header'; + this.content = 'Content'; + } + } + + headerChanged(_opened, _header) { + headerChangedSpy(); + } + + contentChanged(_opened, _content) { + contentChangedSpy(); + } + }, + ); + + beforeEach(async () => { + element = fixtureSync(`<${tag} opened>`); + await element.updateComplete; + }); + + it('should call ready after observers during initialization', () => { + expect(openedChangedSpy).to.be.calledOnce; + expect(headerChangedSpy).to.be.calledTwice; + expect(contentChangedSpy).to.be.calledTwice; + + expect(readySpy).to.be.calledOnce; + expect(readySpy).to.be.calledAfter(openedChangedSpy); + expect(readySpy).to.be.calledAfter(headerChangedSpy); + expect(readySpy).to.be.calledAfter(contentChangedSpy); + }); + }); + describe('setProperties()', () => { let element; diff --git a/packages/date-picker/src/vaadin-lit-date-picker.js b/packages/date-picker/src/vaadin-lit-date-picker.js index b241b3b2d5..24959b9303 100644 --- a/packages/date-picker/src/vaadin-lit-date-picker.js +++ b/packages/date-picker/src/vaadin-lit-date-picker.js @@ -109,8 +109,8 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element } /** @protected */ - firstUpdated() { - super.firstUpdated(); + ready() { + super.ready(); this.addController( new InputController(this, (input) => { diff --git a/packages/number-field/src/vaadin-lit-number-field.js b/packages/number-field/src/vaadin-lit-number-field.js index b30fc9d460..c960e6781f 100644 --- a/packages/number-field/src/vaadin-lit-number-field.js +++ b/packages/number-field/src/vaadin-lit-number-field.js @@ -8,7 +8,6 @@ import { html, LitElement } from 'lit'; import { defineCustomElement } from '@vaadin/component-base/src/define.js'; import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js'; import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js'; -import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js'; import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js'; import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; import { NumberFieldMixin } from './vaadin-number-field-mixin.js'; @@ -84,30 +83,6 @@ class NumberField extends NumberFieldMixin(ThemableMixin(ElementMixin(PolylitMix `; } - - /** @protected */ - ready() { - super.ready(); - - this._tooltipController = new TooltipController(this); - this.addController(this._tooltipController); - this._tooltipController.setPosition('top'); - this._tooltipController.setAriaTarget(this.inputElement); - } - - /** - * Override method from `InputConstraintsMixin` - * to create observer after the initial update - * and preserve invalid state set as attribute. - * - * @protected - * @override - */ - async _createConstraintsObserver() { - await this.updateComplete; - - super._createConstraintsObserver(); - } } defineCustomElement(NumberField); diff --git a/packages/number-field/src/vaadin-number-field-mixin.js b/packages/number-field/src/vaadin-number-field-mixin.js index 231283bb46..286819367e 100644 --- a/packages/number-field/src/vaadin-number-field-mixin.js +++ b/packages/number-field/src/vaadin-number-field-mixin.js @@ -4,6 +4,7 @@ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ */ import { getDeepActiveElement } from '@vaadin/a11y-base/src/focus-utils.js'; +import { TooltipController } from '@vaadin/component-base/src/tooltip-controller'; import { InputController } from '@vaadin/field-base/src/input-controller.js'; import { InputFieldMixin } from '@vaadin/field-base/src/input-field-mixin.js'; import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-controller.js'; @@ -127,6 +128,11 @@ export const NumberFieldMixin = (superClass) => ); this.addController(new LabelledInputController(this.inputElement, this._labelController)); + + this._tooltipController = new TooltipController(this); + this.addController(this._tooltipController); + this._tooltipController.setPosition('top'); + this._tooltipController.setAriaTarget(this.inputElement); } /** diff --git a/packages/number-field/src/vaadin-number-field.js b/packages/number-field/src/vaadin-number-field.js index 40f9304b61..e6abc5a2e2 100644 --- a/packages/number-field/src/vaadin-number-field.js +++ b/packages/number-field/src/vaadin-number-field.js @@ -7,7 +7,6 @@ import '@vaadin/input-container/src/vaadin-input-container.js'; import { html, PolymerElement } from '@polymer/polymer'; import { defineCustomElement } from '@vaadin/component-base/src/define.js'; import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js'; -import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js'; import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js'; import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; import { NumberFieldMixin } from './vaadin-number-field-mixin.js'; @@ -128,16 +127,6 @@ export class NumberField extends NumberFieldMixin(ThemableMixin(ElementMixin(Pol `; } - - /** @protected */ - ready() { - super.ready(); - - this._tooltipController = new TooltipController(this); - this.addController(this._tooltipController); - this._tooltipController.setPosition('top'); - this._tooltipController.setAriaTarget(this.inputElement); - } } defineCustomElement(NumberField); diff --git a/packages/time-picker/src/vaadin-lit-time-picker.js b/packages/time-picker/src/vaadin-lit-time-picker.js index b86e58ea34..1bd695a2fb 100644 --- a/packages/time-picker/src/vaadin-lit-time-picker.js +++ b/packages/time-picker/src/vaadin-lit-time-picker.js @@ -115,8 +115,8 @@ class TimePicker extends TimePickerMixin(ThemableMixin(ElementMixin(PolylitMixin } /** @protected */ - firstUpdated() { - super.firstUpdated(); + ready() { + super.ready(); this.addController( new InputController(