From 0f345ce0e3c7ab992124c9d6d182a86ff2e13b79 Mon Sep 17 00:00:00 2001 From: Serhii Kulykov Date: Wed, 31 Jul 2024 09:51:02 +0300 Subject: [PATCH] refactor: update select to use overlay focus restoration logic (#7601) (#7605) --- .../select/src/vaadin-lit-select-overlay.js | 7 +++++++ .../select/src/vaadin-select-base-mixin.js | 1 - packages/select/src/vaadin-select-overlay.js | 2 ++ packages/select/test/keyboard.common.js | 19 +++++++++++++++++-- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/select/src/vaadin-lit-select-overlay.js b/packages/select/src/vaadin-lit-select-overlay.js index e418320fda..68561e7116 100644 --- a/packages/select/src/vaadin-lit-select-overlay.js +++ b/packages/select/src/vaadin-lit-select-overlay.js @@ -57,6 +57,13 @@ class SelectOverlay extends PositionMixin(OverlayMixin(ThemableMixin(DirMixin(Po `; } + /** @protected */ + ready() { + super.ready(); + + this.restoreFocusOnClose = true; + } + /** @protected */ updated(props) { super.updated(props); diff --git a/packages/select/src/vaadin-select-base-mixin.js b/packages/select/src/vaadin-select-base-mixin.js index 7c8f91060f..08e8ef2f85 100644 --- a/packages/select/src/vaadin-select-base-mixin.js +++ b/packages/select/src/vaadin-select-base-mixin.js @@ -367,7 +367,6 @@ export const SelectBaseMixin = (superClass) => this.removeAttribute('focus-ring'); } } else if (wasOpened) { - this.focus(); if (this._openedWithFocusRing) { this.setAttribute('focus-ring', ''); } diff --git a/packages/select/src/vaadin-select-overlay.js b/packages/select/src/vaadin-select-overlay.js index 7d64ae4d98..6cf3a01c8e 100644 --- a/packages/select/src/vaadin-select-overlay.js +++ b/packages/select/src/vaadin-select-overlay.js @@ -59,6 +59,8 @@ export class SelectOverlay extends PositionMixin(OverlayMixin(DirMixin(ThemableM ready() { super.ready(); + this.restoreFocusOnClose = true; + // When setting `opened` as an attribute, the overlay is already teleported to body // by the time when `ready()` callback of the `vaadin-select` is executed by Polymer, // so querySelector() would return null. So we use this workaround to set properties. diff --git a/packages/select/test/keyboard.common.js b/packages/select/test/keyboard.common.js index e3a4c9922f..143c9890eb 100644 --- a/packages/select/test/keyboard.common.js +++ b/packages/select/test/keyboard.common.js @@ -1,5 +1,5 @@ import { expect } from '@esm-bundle/chai'; -import { fixtureSync, nextRender, nextUpdate } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, nextRender, nextUpdate, outsideClick } from '@vaadin/testing-helpers'; import { sendKeys } from '@web/test-runner-commands'; import sinon from 'sinon'; @@ -67,7 +67,7 @@ describe('keyboard', () => { }); }); - it('should focus value button element on overlay closing', async () => { + it('should focus value button element on overlay closing with Esc', async () => { await sendKeys({ press: 'Tab' }); await sendKeys({ press: 'Enter' }); @@ -81,6 +81,21 @@ describe('keyboard', () => { expect(focusedSpy.calledOnce).to.be.true; }); + it('should focus value button element on overlay closing with outside click', async () => { + await sendKeys({ press: 'Tab' }); + + await sendKeys({ press: 'Enter' }); + await nextRender(); + + const focusedSpy = sinon.spy(valueButton, 'focus'); + + outsideClick(); + await nextUpdate(select); + await aTimeout(0); + + expect(focusedSpy.calledOnce).to.be.true; + }); + it('should restore focus-ring attribute on overlay closing', async () => { await sendKeys({ press: 'Tab' });