diff --git a/packages/virtual-list/src/vaadin-virtual-list-selection-mixin.js b/packages/virtual-list/src/vaadin-virtual-list-selection-mixin.js index f372e745f9..496867cdf5 100644 --- a/packages/virtual-list/src/vaadin-virtual-list-selection-mixin.js +++ b/packages/virtual-list/src/vaadin-virtual-list-selection-mixin.js @@ -286,7 +286,7 @@ export const SelectionMixin = (superClass) => } else { this.removeAttribute('tabindex'); } - this.$.focusexit.hidden = !isFocusable || !this.contains(this.__getActiveElement()); + this.$.focusexit.hidden = !isFocusable; } /** @private */ @@ -352,10 +352,7 @@ export const SelectionMixin = (superClass) => } else { // Focus the focus exit element when tabbing so the focus actually ends up on // the next element in the tab order after the virtual list instead of some focusable child on another row. - // Focusing the focus exit element causes scroll top to get reset, so we need to save and restore it - const scrollTop = this.scrollTop; this.$.focusexit.focus(); - this.scrollTop = scrollTop; } } diff --git a/packages/virtual-list/src/vaadin-virtual-list-styles.js b/packages/virtual-list/src/vaadin-virtual-list-styles.js index b899d4940f..06ffca1f53 100644 --- a/packages/virtual-list/src/vaadin-virtual-list-styles.js +++ b/packages/virtual-list/src/vaadin-virtual-list-styles.js @@ -25,4 +25,9 @@ export const virtualListStyles = css` #items { position: relative; } + + #focusexit { + position: absolute; + top: 0; + } `; diff --git a/packages/virtual-list/test/virtual-list-selection.common.ts b/packages/virtual-list/test/virtual-list-selection.common.ts index 8ad8b3b2c1..da63b114b8 100644 --- a/packages/virtual-list/test/virtual-list-selection.common.ts +++ b/packages/virtual-list/test/virtual-list-selection.common.ts @@ -642,6 +642,13 @@ describe('selection', () => { await nextFrame(); expect(list.hasAttribute('navigating')).to.be.false; }); + + it('should shift tab to an item from outside', async () => { + afterButton.focus(); + await shiftTab(); + + expect(document.activeElement).to.equal(getRenderedItem(0)); + }); }); });