From bb606817d852d5a39a41e1c230af3c1b6c36536b Mon Sep 17 00:00:00 2001 From: Diego Cardoso Date: Mon, 7 Jul 2025 16:43:48 +0200 Subject: [PATCH 1/3] refactor: open date picker overlay on element focus in fullscreen This change overrides the `focus` method to change how focus is handled when the element is in fullscreen mode and it's focused. This is needed to avoid the element being immediatelly removed by the Grid Pro when the user is in a device with small viewport. The element receives focus, but the `_onFocus` listener has a similar detection which removes the focus from the input element, which causes the component to be removed from the cell when used as a custom editor. Part of #9158 --- .../src/vaadin-date-picker-mixin.js | 12 ++++++++++ packages/date-picker/test/fullscreen.test.js | 23 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/packages/date-picker/src/vaadin-date-picker-mixin.js b/packages/date-picker/src/vaadin-date-picker-mixin.js index 6711c778cc5..3e35f340bed 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 008b4117dde..08f144da95c 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); From 26b630380228ef735510ff417bafed67f98c9709 Mon Sep 17 00:00:00 2001 From: Diego Cardoso Date: Fri, 11 Jul 2025 16:24:10 +0200 Subject: [PATCH 2/3] refactor: change fullscreen detection in field highlighter --- .../src/fields/vaadin-date-picker-observer.js | 21 +++++-------------- .../test/field-components.test.js | 5 ----- 2 files changed, 5 insertions(+), 21 deletions(-) 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 eb29518e75a..32f27c42980 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 e7cb5687a7a..ff8657d9ddf 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(); From 973b8bd69a9b5a4fdc2ccbe0b89482d1859b597f Mon Sep 17 00:00:00 2001 From: Serhii Kulykov Date: Mon, 14 Jul 2025 12:08:00 +0300 Subject: [PATCH 3/3] Update packages/date-picker/src/vaadin-date-picker-mixin.js --- packages/date-picker/src/vaadin-date-picker-mixin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/date-picker/src/vaadin-date-picker-mixin.js b/packages/date-picker/src/vaadin-date-picker-mixin.js index 3e35f340bed..026b8112b7f 100644 --- a/packages/date-picker/src/vaadin-date-picker-mixin.js +++ b/packages/date-picker/src/vaadin-date-picker-mixin.js @@ -472,7 +472,7 @@ export const DatePickerMixin = (subclass) => /** * @protected * @override - * */ + */ focus(options) { if (this._noInput && !isKeyboardActive()) { this.open();