Skip to content

Commit e28c30d

Browse files
DiegoCardosovaadin-bot
authored andcommitted
refactor: open date picker overlay on element focus in fullscreen (#9670)
1 parent cfc81ec commit e28c30d

File tree

4 files changed

+40
-21
lines changed

4 files changed

+40
-21
lines changed

packages/date-picker/src/vaadin-date-picker-mixin.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,18 @@ export const DatePickerMixin = (subclass) =>
496496
this.opened = false;
497497
}
498498

499+
/**
500+
* @protected
501+
* @override
502+
*/
503+
focus(options) {
504+
if (this._noInput && !isKeyboardActive()) {
505+
this.open();
506+
} else {
507+
super.focus(options);
508+
}
509+
}
510+
499511
/**
500512
* Opens the dropdown.
501513
*/

packages/date-picker/test/fullscreen.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,21 @@ describe('fullscreen mode', () => {
6060
expect(document.activeElement).to.not.equal(input);
6161
});
6262

63+
it('should not focus input element when focusing the date picker', () => {
64+
const spy = sinon.spy(input, 'focus');
65+
datePicker.focus();
66+
expect(spy.called).to.be.false;
67+
expect(document.activeElement).to.not.equal(input);
68+
});
69+
70+
it('should focus date element when focusing the date picker', async () => {
71+
datePicker.focus();
72+
await untilOverlayRendered(datePicker);
73+
const cell = getFocusableCell(datePicker);
74+
expect(cell).to.be.instanceOf(HTMLTableCellElement);
75+
expect(cell.getAttribute('part')).to.include('today');
76+
});
77+
6378
it('should not blur input element when focusing it with keyboard', () => {
6479
const spy = sinon.spy(input, 'blur');
6580
tabKeyDown(input);
@@ -68,6 +83,14 @@ describe('fullscreen mode', () => {
6883
expect(document.activeElement).to.equal(input);
6984
});
7085

86+
it('should not blur input element when focusing date picker with keyboard', () => {
87+
const spy = sinon.spy(input, 'blur');
88+
tabKeyDown(input);
89+
datePicker.focus();
90+
expect(spy.called).to.be.false;
91+
expect(document.activeElement).to.equal(input);
92+
});
93+
7194
it('should blur input element when opening overlay', async () => {
7295
const spy = sinon.spy(input, 'blur');
7396
await open(datePicker);

packages/field-highlighter/src/fields/vaadin-date-picker-observer.js

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
* Copyright (c) 2021 - 2025 Vaadin Ltd.
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
6+
import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
67
import { ComponentObserver } from './vaadin-component-observer.js';
78

89
export class DatePickerObserver extends ComponentObserver {
910
constructor(datePicker) {
1011
super(datePicker);
1112

1213
this.datePicker = datePicker;
13-
this.fullscreenFocus = false;
1414
this.blurWhileOpened = false;
1515

1616
this.addListeners(datePicker);
@@ -19,14 +19,6 @@ export class DatePickerObserver extends ComponentObserver {
1919
addListeners(datePicker) {
2020
this.overlay = datePicker.$.overlay;
2121

22-
// Fullscreen date picker calls blur() to avoid focusing of the input:
23-
// 1. first time when focus event is fired (before opening the overlay),
24-
// 2. second time after the overlay is open, see "_onOverlayOpened".
25-
// Here we set the flag to ignore related focusout events and then to
26-
// mark date picker as being edited by user (to show field highlight).
27-
// We have to use capture phase in order to catch this event early.
28-
datePicker.addEventListener('blur', (event) => this.onBlur(event), true);
29-
3022
datePicker.addEventListener('opened-changed', (event) => this.onOpenedChanged(event));
3123

3224
this.overlay.addEventListener('focusout', (event) => this.onOverlayFocusOut(event));
@@ -40,11 +32,9 @@ export class DatePickerObserver extends ComponentObserver {
4032
return this.datePicker._overlayContent && this.datePicker._overlayContent.contains(node);
4133
}
4234

43-
onBlur(event) {
35+
isFullscreen() {
4436
const datePicker = this.datePicker;
45-
if (datePicker._fullscreen && !this.isEventInOverlay(event.relatedTarget)) {
46-
this.fullscreenFocus = true;
47-
}
37+
return datePicker._noInput && !isKeyboardActive();
4838
}
4939

5040
onFocusIn(event) {
@@ -63,7 +53,7 @@ export class DatePickerObserver extends ComponentObserver {
6353
}
6454

6555
onFocusOut(event) {
66-
if (this.fullscreenFocus || this.isEventInOverlay(event.relatedTarget)) {
56+
if (this.isEventInOverlay(event.relatedTarget)) {
6757
// Do nothing, overlay is opening.
6858
} else if (!this.datePicker.opened) {
6959
// Field blur when closed.
@@ -83,8 +73,7 @@ export class DatePickerObserver extends ComponentObserver {
8373
}
8474

8575
onOpenedChanged(event) {
86-
if (event.detail.value === true && this.fullscreenFocus) {
87-
this.fullscreenFocus = false;
76+
if (event.detail.value === true && this.isFullscreen()) {
8877
this.showOutline(this.datePicker);
8978
}
9079

packages/field-highlighter/test/field-components.test.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,6 @@ describe('field components', () => {
161161
field._fullscreen = true;
162162
});
163163

164-
it('should not dispatch vaadin-highlight-show event on focus', () => {
165-
field.focus();
166-
expect(showSpy.callCount).to.equal(0);
167-
});
168-
169164
it('should dispatch vaadin-highlight-show event on open', async () => {
170165
field.focus();
171166
field.click();

0 commit comments

Comments
 (0)