diff --git a/packages/date-picker/src/vaadin-date-picker-mixin.js b/packages/date-picker/src/vaadin-date-picker-mixin.js index 6711c778cc..3e35f340be 100644 --- a/packages/date-picker/src/vaadin-date-picker-mixin.js +++ b/packages/date-picker/src/vaadin-date-picker-mixin.js @@ -469,6 +469,18 @@ export const DatePickerMixin = (subclass) => this.opened = false; } + /** + * @protected + * @override + * */ + focus(options) { + if (this._noInput && !isKeyboardActive()) { + this.open(); + } else { + super.focus(options); + } + } + /** * Opens the dropdown. */ diff --git a/packages/date-picker/test/fullscreen.test.js b/packages/date-picker/test/fullscreen.test.js index 008b4117dd..08f144da95 100644 --- a/packages/date-picker/test/fullscreen.test.js +++ b/packages/date-picker/test/fullscreen.test.js @@ -59,6 +59,21 @@ describe('fullscreen mode', () => { expect(document.activeElement).to.not.equal(input); }); + it('should not focus input element when focusing the date picker', () => { + const spy = sinon.spy(input, 'focus'); + datePicker.focus(); + expect(spy.called).to.be.false; + expect(document.activeElement).to.not.equal(input); + }); + + it('should focus date element when focusing the date picker', async () => { + datePicker.focus(); + await untilOverlayRendered(datePicker); + const cell = getFocusableCell(datePicker); + expect(cell).to.be.instanceOf(HTMLTableCellElement); + expect(cell.getAttribute('part')).to.include('today'); + }); + it('should not blur input element when focusing it with keyboard', () => { const spy = sinon.spy(input, 'blur'); tabKeyDown(input); @@ -67,6 +82,14 @@ describe('fullscreen mode', () => { expect(document.activeElement).to.equal(input); }); + it('should not blur input element when focusing date picker with keyboard', () => { + const spy = sinon.spy(input, 'blur'); + tabKeyDown(input); + datePicker.focus(); + expect(spy.called).to.be.false; + expect(document.activeElement).to.equal(input); + }); + it('should blur input element when opening overlay', async () => { const spy = sinon.spy(input, 'blur'); await open(datePicker); diff --git a/packages/field-highlighter/src/fields/vaadin-date-picker-observer.js b/packages/field-highlighter/src/fields/vaadin-date-picker-observer.js index eb29518e75..32f27c4298 100644 --- a/packages/field-highlighter/src/fields/vaadin-date-picker-observer.js +++ b/packages/field-highlighter/src/fields/vaadin-date-picker-observer.js @@ -3,6 +3,7 @@ * Copyright (c) 2021 - 2025 Vaadin Ltd. * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ */ +import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js'; import { ComponentObserver } from './vaadin-component-observer.js'; export class DatePickerObserver extends ComponentObserver { @@ -10,7 +11,6 @@ export class DatePickerObserver extends ComponentObserver { super(datePicker); this.datePicker = datePicker; - this.fullscreenFocus = false; this.blurWhileOpened = false; this.addListeners(datePicker); @@ -19,14 +19,6 @@ export class DatePickerObserver extends ComponentObserver { addListeners(datePicker) { this.overlay = datePicker.$.overlay; - // Fullscreen date picker calls blur() to avoid focusing of the input: - // 1. first time when focus event is fired (before opening the overlay), - // 2. second time after the overlay is open, see "_onOverlayOpened". - // Here we set the flag to ignore related focusout events and then to - // mark date picker as being edited by user (to show field highlight). - // We have to use capture phase in order to catch this event early. - datePicker.addEventListener('blur', (event) => this.onBlur(event), true); - datePicker.addEventListener('opened-changed', (event) => this.onOpenedChanged(event)); this.overlay.addEventListener('focusout', (event) => this.onOverlayFocusOut(event)); @@ -40,11 +32,9 @@ export class DatePickerObserver extends ComponentObserver { return this.datePicker._overlayContent && this.datePicker._overlayContent.contains(node); } - onBlur(event) { + isFullscreen() { const datePicker = this.datePicker; - if (datePicker._fullscreen && !this.isEventInOverlay(event.relatedTarget)) { - this.fullscreenFocus = true; - } + return datePicker._noInput && !isKeyboardActive(); } onFocusIn(event) { @@ -63,7 +53,7 @@ export class DatePickerObserver extends ComponentObserver { } onFocusOut(event) { - if (this.fullscreenFocus || this.isEventInOverlay(event.relatedTarget)) { + if (this.isEventInOverlay(event.relatedTarget)) { // Do nothing, overlay is opening. } else if (!this.datePicker.opened) { // Field blur when closed. @@ -83,8 +73,7 @@ export class DatePickerObserver extends ComponentObserver { } onOpenedChanged(event) { - if (event.detail.value === true && this.fullscreenFocus) { - this.fullscreenFocus = false; + if (event.detail.value === true && this.isFullscreen()) { this.showOutline(this.datePicker); } diff --git a/packages/field-highlighter/test/field-components.test.js b/packages/field-highlighter/test/field-components.test.js index e7cb5687a7..ff8657d9dd 100644 --- a/packages/field-highlighter/test/field-components.test.js +++ b/packages/field-highlighter/test/field-components.test.js @@ -160,11 +160,6 @@ describe('field components', () => { field._fullscreen = true; }); - it('should not dispatch vaadin-highlight-show event on focus', () => { - field.focus(); - expect(showSpy.callCount).to.equal(0); - }); - it('should dispatch vaadin-highlight-show event on open', async () => { field.focus(); field.click();