Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions src/__tests__/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
`)
Expand Down Expand Up @@ -418,6 +418,26 @@ test('should not focus disabled elements', () => {
expect(five).toHaveFocus()
})

test('should not focus elements inside a hidden parent', () => {
setup(`
<div>
<input data-testid="one" />
<div hidden="">
<button>click</button>
</div>
<input data-testid="three" />
</div>`)

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(`<button disabled>no clicky</button>`)
userEvent.tab()
Expand Down
6 changes: 5 additions & 1 deletion src/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down