diff --git a/src/vaadin-text-area.html b/src/vaadin-text-area.html index c6e8c2b6..480187ea 100644 --- a/src/vaadin-text-area.html +++ b/src/vaadin-text-area.html @@ -192,15 +192,7 @@ inputField.style.removeProperty('display'); inputField.scrollTop = scrollTop; - if (this.__previousInputHeight && this.__previousInputHeight !== inputHeight) { - this.dispatchEvent( - new CustomEvent('iron-resize', { - bubbles: true - }) - ); - } - - this.__previousInputHeight = inputHeight; + this._dispatchIronResizeEventIfNeeded('InputHeight', inputHeight); } /** diff --git a/src/vaadin-text-field-mixin.html b/src/vaadin-text-field-mixin.html index 273319cc..1e5aede9 100644 --- a/src/vaadin-text-field-mixin.html +++ b/src/vaadin-text-field-mixin.html @@ -318,7 +318,9 @@ '_hostPropsChanged(' + HOST_PROPS.default.join(', ') + ')', '_hostAccessiblePropsChanged(' + HOST_PROPS.accessible.join(', ') + ')', '_getActiveErrorId(invalid, errorMessage, _errorId)', - '_getActiveLabelId(label, _labelId)']; + '_getActiveLabelId(label, _labelId)', + '__observeOffsetHeight(errorMessage, invalid, label)' + ]; } get focusElement() { @@ -560,6 +562,13 @@ var uniqueId = Vaadin.TextFieldMixin._uniqueId = 1 + Vaadin.TextFieldMixin._uniqueId || 0; this._errorId = `${this.constructor.is}-error-${uniqueId}`; this._labelId = `${this.constructor.is}-label-${uniqueId}`; + + // Lumo theme defines a max-height transition for the "error-message" + // part on invalid state change. + this.shadowRoot.querySelector('[part="error-message"]') + .addEventListener('transitionend', () => { + this.__observeOffsetHeight(); + }); } /** @@ -660,6 +669,22 @@ return (!(errorMessage && invalid ? errorId : undefined)).toString(); } + _dispatchIronResizeEventIfNeeded(sizePropertyName, value) { + const previousSizePropertyName = '__previous' + sizePropertyName; + if (this[previousSizePropertyName] !== undefined + && this[previousSizePropertyName] !== value) { + this.dispatchEvent( + new CustomEvent('iron-resize', {bubbles: true}) + ); + } + + this[previousSizePropertyName] = value; + } + + __observeOffsetHeight() { + this._dispatchIronResizeEventIfNeeded('Height', this.offsetHeight); + } + /** * @protected */ @@ -697,5 +722,11 @@ * * @event input */ + + /** + * Fired when the size of the element changes. + * + * @event iron-resize + */ }; diff --git a/test/text-field.html b/test/text-field.html index cee3f081..75799d67 100644 --- a/test/text-field.html +++ b/test/text-field.html @@ -481,6 +481,59 @@ textField.clear(); expect(textField.inputElement.value).to.equal(''); }); + + describe(`resize notification ${condition}`, () => { + let textField, spy; + + beforeEach(() => { + textField = fixture(`default${fixtureName}`); + spy = sinon.spy(); + textField.addEventListener('iron-resize', spy); + }); + + it('should not dispatch `iron-resize` event on init', () => { + expect(spy).to.not.be.called; + }); + + it('should dispatch `iron-resize` event on invalid height change', done => { + // Lumo theme defines a max-height transition for the "error-message" + // part on invalid state change. + + // NOTE(platosha): Transition events are unreilable, IE skips + // the transition sometimes, Safari does not fire anything but + // 'transitionend', so transitions are hard to detect properly. + // Have to use a timeout here and in the next test instead. + setTimeout(() => { + expect(spy).to.be.called; + done(); + }, 1000); + + textField.errorMessage = 'Error'; + textField.invalid = true; + }); + + it('should dispatch `iron-resize` event on error message height change', done => { + // Lumo theme defines a max-height transition for the "error-message" + // part on invalid state change. + setTimeout(() => { + spy.reset(); + + // Long message that spans on multiple lines + textField.errorMessage = [...new Array(42)].map(() => 'bla').join(' '); + + expect(spy).to.be.calledOnce; + done(); + }, 1000); + + textField.errorMessage = 'Error'; + textField.invalid = true; + }); + + it('should dispatch `iron-resize` event on label height change', () => { + textField.label = 'Label'; + expect(spy).to.be.calledOnce; + }); + }); }); }); diff --git a/test/visual/screens/vaadin-text-field/text-area-rtl-material/rtl/chrome.png b/test/visual/screens/vaadin-text-field/text-area-rtl-material/rtl/chrome.png index 12747e44..e4f8b164 100644 Binary files a/test/visual/screens/vaadin-text-field/text-area-rtl-material/rtl/chrome.png and b/test/visual/screens/vaadin-text-field/text-area-rtl-material/rtl/chrome.png differ