diff --git a/packages/multi-select-combo-box/src/vaadin-multi-select-combo-box-internal.js b/packages/multi-select-combo-box/src/vaadin-multi-select-combo-box-internal.js index 3f49a5c04c..4f297baa9a 100644 --- a/packages/multi-select-combo-box/src/vaadin-multi-select-combo-box-internal.js +++ b/packages/multi-select-combo-box/src/vaadin-multi-select-combo-box-internal.js @@ -149,6 +149,12 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi return 'vaadin-multi-select-combo-box'; } + constructor() { + super(); + + this.addEventListener('custom-value-set', this.__onCustomValueSet.bind(this)); + } + /** * Override method inherited from the combo-box * to allow opening dropdown when readonly. @@ -449,6 +455,15 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi super.clearCache(); } + + /** @private */ + __onCustomValueSet(event) { + // Prevent setting custom value on input blur or outside click, + // so it can be only committed explicitly by pressing Enter. + if (this._ignoreCommitValue) { + event.stopImmediatePropagation(); + } + } } customElements.define(MultiSelectComboBoxInternal.is, MultiSelectComboBoxInternal); diff --git a/packages/multi-select-combo-box/test/basic.test.js b/packages/multi-select-combo-box/test/basic.test.js index e1c6b874c2..ddf1576efe 100644 --- a/packages/multi-select-combo-box/test/basic.test.js +++ b/packages/multi-select-combo-box/test/basic.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import { fixtureSync, nextRender } from '@vaadin/testing-helpers'; -import { sendKeys } from '@web/test-runner-commands'; +import { resetMouse, sendKeys, sendMouse } from '@web/test-runner-commands'; import sinon from 'sinon'; import './not-animated-styles.js'; import '../vaadin-multi-select-combo-box.js'; @@ -320,6 +320,23 @@ describe('basic', () => { await sendKeys({ down: 'Enter' }); expect(comboBox.selectedItems).to.deep.equal(['apple']); }); + + it('should not fire custom-value-set event when pressing Tab', async () => { + const spy = sinon.spy(); + comboBox.addEventListener('custom-value-set', spy); + await sendKeys({ type: 'pear' }); + await sendKeys({ down: 'Tab' }); + expect(spy.called).to.be.false; + }); + + it('should not fire custom-value-set event on outside click', async () => { + const spy = sinon.spy(); + comboBox.addEventListener('custom-value-set', spy); + await sendKeys({ type: 'ap' }); + await sendMouse({ type: 'click', position: [200, 200] }); + await resetMouse(); + expect(spy.called).to.be.false; + }); }); describe('helper text', () => { diff --git a/packages/multi-select-combo-box/test/selecting-items.test.js b/packages/multi-select-combo-box/test/selecting-items.test.js index 7c1f151946..c6f8b00337 100644 --- a/packages/multi-select-combo-box/test/selecting-items.test.js +++ b/packages/multi-select-combo-box/test/selecting-items.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import { fixtureSync, nextRender } from '@vaadin/testing-helpers'; -import { sendKeys } from '@web/test-runner-commands'; +import { resetMouse, sendKeys, sendMouse } from '@web/test-runner-commands'; import sinon from 'sinon'; import './not-animated-styles.js'; import '../vaadin-multi-select-combo-box.js'; @@ -113,6 +113,21 @@ describe('selecting items', () => { expect(comboBox.selectedItems).to.deep.equal(['apple']); }); + it('should not select an item on outside click when it is focused', async () => { + await sendKeys({ down: 'ArrowDown' }); + await sendKeys({ down: 'ArrowDown' }); + await sendMouse({ type: 'click', position: [200, 200] }); + await resetMouse(); + expect(comboBox.selectedItems).to.deep.equal([]); + }); + + it('should not select an item on blur when it is focused', async () => { + await sendKeys({ down: 'ArrowDown' }); + await sendKeys({ down: 'ArrowDown' }); + await sendKeys({ down: 'Tab' }); + expect(comboBox.selectedItems).to.deep.equal([]); + }); + it('should un-select item when using clear() method', () => { comboBox.selectedItems = ['orange']; comboBox.clear();