diff --git a/packages/date-picker/src/vaadin-date-picker-mixin.js b/packages/date-picker/src/vaadin-date-picker-mixin.js index 83265a1999b..f6a50128ac6 100644 --- a/packages/date-picker/src/vaadin-date-picker-mixin.js +++ b/packages/date-picker/src/vaadin-date-picker-mixin.js @@ -459,7 +459,10 @@ export const DatePickerMixin = (subclass) => super._onFocus(event); if (this._noInput && !isKeyboardActive()) { + // Blur to hide the virtual keyboard, but do not validate. + this.__ignoreInternalBlur = true; event.target.blur(); + this.__ignoreInternalBlur = false; } } @@ -470,6 +473,10 @@ export const DatePickerMixin = (subclass) => _onBlur(event) { super._onBlur(event); + if (this.__ignoreInternalBlur) { + return; + } + if (!this.opened) { this.__commitParsedOrFocusedDate(); diff --git a/packages/date-picker/test/fullscreen.test.js b/packages/date-picker/test/fullscreen.test.js index 08f144da95c..707045c1aac 100644 --- a/packages/date-picker/test/fullscreen.test.js +++ b/packages/date-picker/test/fullscreen.test.js @@ -1,6 +1,6 @@ import { expect } from '@vaadin/chai-plugins'; import { sendKeys, setViewport } from '@vaadin/test-runner-commands'; -import { aTimeout, fixtureSync, nextRender, outsideClick, tabKeyDown, tap } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, nextRender, nextUpdate, outsideClick, tabKeyDown, tap } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import '../src/vaadin-date-picker.js'; import { getFocusableCell, open, touchTap, untilOverlayRendered } from './helpers.js'; @@ -156,6 +156,60 @@ describe('fullscreen mode', () => { }); }); + describe('validation', () => { + let validateSpy; + + beforeEach(async () => { + datePicker.required = true; + await nextUpdate(datePicker); + validateSpy = sinon.spy(datePicker, 'validate'); + }); + + it('should not validate when focusing the input', () => { + input.focus(); + expect(validateSpy.called).to.be.false; + expect(datePicker.invalid).to.be.false; + }); + + it('should not validate when opening overlay on input tap', async () => { + input.focus(); + tap(input); + await untilOverlayRendered(datePicker); + expect(validateSpy.called).to.be.false; + expect(datePicker.invalid).to.be.false; + }); + + it('should validate when closing overlay on outside click', async () => { + await open(datePicker); + validateSpy.resetHistory(); + + outsideClick(); + await nextRender(); + + expect(validateSpy.called).to.be.true; + expect(datePicker.invalid).to.be.true; + }); + + it('should validate on blur after the input has been blurred internally', async () => { + input.focus(); + tap(input); + await untilOverlayRendered(datePicker); + datePicker.close(); + await nextRender(); + + // Make the input focusable + datePicker.autoOpenDisabled = true; + await nextUpdate(datePicker); + validateSpy.resetHistory(); + + input.focus(); + input.blur(); + + expect(validateSpy.called).to.be.true; + expect(datePicker.invalid).to.be.true; + }); + }); + describe('buttons', () => { let overlayContent;