diff --git a/packages/select/src/vaadin-select-base-mixin.js b/packages/select/src/vaadin-select-base-mixin.js index acec115c9a..3fa2b7da52 100644 --- a/packages/select/src/vaadin-select-base-mixin.js +++ b/packages/select/src/vaadin-select-base-mixin.js @@ -512,23 +512,21 @@ export const SelectBaseMixin = (superClass) => valueButton.removeAttribute('placeholder'); - if (!selected) { - if (this.placeholder) { - const item = this.__createItemElement({ label: this.placeholder }); - this.__appendValueItemElement(item, valueButton); - valueButton.setAttribute('placeholder', ''); - } - } else { + if (this._hasContent(selected)) { this.__attachSelectedItem(selected); + } else if (this.placeholder) { + const item = this.__createItemElement({ label: this.placeholder }); + this.__appendValueItemElement(item, valueButton); + valueButton.setAttribute('placeholder', ''); + } - if (!this._valueChanging) { - this._selectedChanging = true; - this.value = selected.value || ''; - if (this.__dispatchChangePending) { - this.__dispatchChange(); - } - delete this._selectedChanging; + if (!this._valueChanging && selected) { + this._selectedChanging = true; + this.value = selected.value || ''; + if (this.__dispatchChangePending) { + this.__dispatchChange(); } + delete this._selectedChanging; } const labelledIdReferenceConfig = @@ -540,6 +538,14 @@ export const SelectBaseMixin = (superClass) => } } + /** @private */ + _hasContent(item) { + if (!item) { + return false; + } + return Boolean(item.hasAttribute('label') ? item.getAttribute('label') : item.textContent.trim()); + } + /** @private */ _updateSelectedItem(value, items) { if (items) { diff --git a/packages/select/test/select.common.js b/packages/select/test/select.common.js index f5aeb0b803..a8e55ec645 100644 --- a/packages/select/test/select.common.js +++ b/packages/select/test/select.common.js @@ -447,9 +447,28 @@ describe('vaadin-select', () => { }); describe('placeholder', () => { + beforeEach(() => { + select.placeholder = 'Select an item'; + }); + it('should set placeholder as a value node text content', async () => { select.value = null; - select.placeholder = 'Select an item'; + await nextUpdate(select); + expect(valueButton.textContent).to.equal('Select an item'); + }); + + it('should show placeholder when selecting an item with empty label', async () => { + select.opened = true; + await nextRender(); + click(select._items[4]); + await nextUpdate(select); + expect(valueButton.textContent).to.equal('Select an item'); + }); + + it('should show placeholder when selecting an item with empty text', async () => { + select.opened = true; + await nextRender(); + click(select._items[3]); await nextUpdate(select); expect(valueButton.textContent).to.equal('Select an item'); });