diff --git a/packages/time-picker/src/vaadin-time-picker-combo-box.js b/packages/time-picker/src/vaadin-time-picker-combo-box.js index 7fdc8ef97d..411adf60f5 100644 --- a/packages/time-picker/src/vaadin-time-picker-combo-box.js +++ b/packages/time-picker/src/vaadin-time-picker-combo-box.js @@ -71,6 +71,27 @@ class TimePickerComboBox extends ComboBoxMixin(ThemableMixin(PolymerElement)) { return this.querySelector('[part="clear-button"]'); } + /** + * @override + * @protected + */ + get _inputElementValue() { + return super._inputElementValue; + } + + /** + * The setter is overridden to ensure the `_hasInputValue` property + * doesn't wrongly indicate true after the input element's value + * is reverted or cleared programmatically. + * + * @override + * @protected + */ + set _inputElementValue(value) { + super._inputElementValue = value; + this._hasInputValue = value.length > 0; + } + /** @protected */ ready() { super.ready(); diff --git a/packages/time-picker/src/vaadin-time-picker.js b/packages/time-picker/src/vaadin-time-picker.js index 87154983a0..728f9967fb 100644 --- a/packages/time-picker/src/vaadin-time-picker.js +++ b/packages/time-picker/src/vaadin-time-picker.js @@ -125,6 +125,7 @@ class TimePicker extends PatternMixin(InputControlMixin(ThemableMixin(ElementMix position-target="[[_inputContainer]]" theme$="[[_theme]]" on-change="__onComboBoxChange" + on-has-input-value-changed="__onComboBoxHasInputValueChanged" > { - let timePicker, comboBox; + let timePicker; describe('change event', () => { let changeSpy, inputElement; beforeEach(() => { timePicker = fixtureSync(``); - comboBox = timePicker.$.comboBox; inputElement = timePicker.inputElement; changeSpy = sinon.spy(); timePicker.addEventListener('change', changeSpy); @@ -96,4 +95,85 @@ describe('events', () => { expect(changeSpy.callCount).to.equal(1); }); }); + + describe('has-input-value-changed event', () => { + let clearButton, hasInputValueChangedSpy, valueChangedSpy; + + beforeEach(async () => { + hasInputValueChangedSpy = sinon.spy(); + valueChangedSpy = sinon.spy(); + timePicker = fixtureSync(''); + clearButton = timePicker.shadowRoot.querySelector('[part=clear-button]'); + timePicker.addEventListener('has-input-value-changed', hasInputValueChangedSpy); + timePicker.addEventListener('value-changed', valueChangedSpy); + timePicker.inputElement.focus(); + }); + + describe('without value', () => { + it('should be fired when entering user input', async () => { + await sendKeys({ type: '12:00' }); + expect(hasInputValueChangedSpy.calledOnce).to.be.true; + }); + + describe('with user input', () => { + beforeEach(async () => { + await sendKeys({ type: '12:00' }); + hasInputValueChangedSpy.resetHistory(); + }); + + it('should be fired when clearing the user input with Esc', async () => { + // Clear selection in the dropdown. + await sendKeys({ press: 'Escape' }); + // Clear the user input. + await sendKeys({ press: 'Escape' }); + expect(timePicker.inputElement.value).to.be.empty; + expect(hasInputValueChangedSpy.calledOnce).to.be.true; + }); + }); + + describe('with bad user input', async () => { + beforeEach(async () => { + await sendKeys({ type: 'foo' }); + hasInputValueChangedSpy.resetHistory(); + }); + + it('should be fired when clearing bad user input with Esc', async () => { + await sendKeys({ press: 'Escape' }); + expect(hasInputValueChangedSpy.calledOnce).to.be.true; + }); + + it('should be fired when clearing committed bad user input with Esc', async () => { + await sendKeys({ press: 'Enter' }); + hasInputValueChangedSpy.resetHistory(); + await sendKeys({ press: 'Escape' }); + expect(hasInputValueChangedSpy.calledOnce).to.be.true; + }); + }); + }); + + describe('with value', () => { + beforeEach(async () => { + await sendKeys({ type: '10:00' }); + await sendKeys({ press: 'Enter' }); + valueChangedSpy.resetHistory(); + hasInputValueChangedSpy.resetHistory(); + }); + + it('should be fired on clear button click', () => { + clearButton.click(); + expect(timePicker.inputElement.value).to.be.empty; + expect(valueChangedSpy.calledOnce).to.be.true; + expect(hasInputValueChangedSpy.calledOnce).to.be.true; + expect(hasInputValueChangedSpy.calledBefore(valueChangedSpy)).to.be.true; + }); + + it('should be fired when clearing the value with Esc', async () => { + await sendKeys({ press: 'Escape' }); + expect(timePicker.inputElement.value).to.be.empty; + expect(valueChangedSpy.calledOnce).to.be.true; + expect(hasInputValueChangedSpy.calledOnce).to.be.true; + expect(hasInputValueChangedSpy.calledBefore(valueChangedSpy)).to.be.true; + }); + }); + }); });