diff --git a/src/__tests__/tab.js b/src/__tests__/tab.js index de9d0f46..fbd0493d 100644 --- a/src/__tests__/tab.js +++ b/src/__tests__/tab.js @@ -17,7 +17,7 @@ test('fires events when tabbing between two elements', () => { userEvent.tab() expect(getEventSnapshot()).toMatchInlineSnapshot(` Events fired on: div - + input#a[value=""] - keydown: Tab (9) input#a[value=""] - focusout input#b[value=""] - focusin @@ -45,7 +45,7 @@ test('does not change focus if default prevented on keydown', () => { userEvent.tab() expect(getEventSnapshot()).toMatchInlineSnapshot(` Events fired on: div - + input#a[value=""] - keydown: Tab (9) input#a[value=""] - keyup: Tab (9) `) @@ -418,6 +418,26 @@ test('should not focus disabled elements', () => { expect(five).toHaveFocus() }) +test('should not focus elements inside a hidden parent', () => { + setup(` +
+ + + +
`) + + const one = document.querySelector('[data-testid="one"]') + const three = document.querySelector('[data-testid="three"]') + + userEvent.tab() + expect(one).toHaveFocus() + + userEvent.tab() + expect(three).toHaveFocus() +}) + test('should keep focus on the document if there are no enabled, focusable elements', () => { setup(``) userEvent.tab() diff --git a/src/tab.js b/src/tab.js index 4bca7ff6..5205684b 100644 --- a/src/tab.js +++ b/src/tab.js @@ -31,7 +31,11 @@ function tab({shift = false, focusTrap} = {}) { const enabledElements = [...focusableElements].filter( el => el === previousElement || - (el.getAttribute('tabindex') !== '-1' && !el.disabled), + (el.getAttribute('tabindex') !== '-1' && + !el.disabled && + // Hidden elements are taken out of the + // document, along with all their children. + !el.closest('[hidden]')), ) if (enabledElements.length === 0) return