Skip to content

Commit

Permalink
feat(keyboard): support shadow DOM in tab order
Browse files Browse the repository at this point in the history
  • Loading branch information
ph-fritsche committed Aug 19, 2022
1 parent b322220 commit 7756374
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 17 deletions.
29 changes: 14 additions & 15 deletions src/utils/focus/focusable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,17 @@ export function findFocusable(
}
}

// TODO: use for tab
// /**
// * Find the all focusable elements in a DOM tree.
// */
// export function findAllFocusable(element: Element | ShadowRoot): HTMLElement[] {
// const all: HTMLElement[] = []
// for (const el of Array.from(element.querySelectorAll('*'))) {
// if (isFocusable(el)) {
// all.push(el)
// } else if (el.shadowRoot) {
// all.push(...findAllFocusable(el.shadowRoot))
// }
// }
// return all
// }
/**
* Find the all focusable elements in a DOM tree.
*/
export function findAllFocusable(element: Element | ShadowRoot): HTMLElement[] {
const all: HTMLElement[] = []
for (const el of Array.from(element.querySelectorAll('*'))) {
if (isFocusable(el)) {
all.push(el)
} else if (el.shadowRoot) {
all.push(...findAllFocusable(el.shadowRoot))
}
}
return all
}
4 changes: 2 additions & 2 deletions src/utils/focus/getTabDestination.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {isDisabled} from '../misc/isDisabled'
import {isElementType} from '../misc/isElementType'
import {isVisible} from '../misc/isVisible'
import {FOCUSABLE_SELECTOR} from './focusable'
import {findAllFocusable} from './focusable'

export function getTabDestination(activeElement: Element, shift: boolean) {
const document = activeElement.ownerDocument
const focusableElements = document.querySelectorAll(FOCUSABLE_SELECTOR)
const focusableElements = findAllFocusable(document.body)

const enabledElements = Array.from(focusableElements).filter(
el =>
Expand Down
24 changes: 24 additions & 0 deletions tests/utils/focus/getTabDestination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,27 @@ test('skip unchecked radios if group has one checked', () => {
expect(getTabDestination(elF, false)).toBe(elG)
expect(getTabDestination(elF, true)).toBe(elE)
})

test('tab through shadow trees', () => {
const {query} = setup(`
<input id="a"/>
<shadow-host innerHTML='
<input id="b"/>
<shadow-host innerHTML=&apos;
<input id="c"/>
<input id="d"/>
&apos;></shadow-host>
<input id="e"/>
'></shadow-host>
<input id="f"/>
`)

assertTabOrder([
query('#a'),
query('shadow-host', '#b'),
query('shadow-host', 'shadow-host', '#c'),
query('shadow-host', 'shadow-host', '#d'),
query('shadow-host', '#e'),
query('#f'),
])
})

0 comments on commit 7756374

Please sign in to comment.