Skip to content

Commit

Permalink
Add observer to focus-trap behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
TylerJDev committed Aug 6, 2024
1 parent 0d55a64 commit 04fa6a8
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/focus-trap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,25 @@ function followSignal(signal: AbortSignal): AbortController {
return controller
}

function observeFocusTrap(container: HTMLElement, sentinels: HTMLElement[]) {
const observer = new MutationObserver(mutations => {
for (const mutation of mutations) {
if (mutation.type === 'childList' && mutation.addedNodes.length) {
// If the first and last children of container aren't sentinels, move them to the start and end
const firstChild = container.firstElementChild
const lastChild = container.lastElementChild

if (!firstChild?.classList.contains('sentinel')) container.insertAdjacentElement('afterbegin', sentinels[0])
if (!lastChild?.classList.contains('sentinel')) container.insertAdjacentElement('beforeend', sentinels[1])
}
}
})

observer.observe(container, {childList: true})

return observer
}

/**
* Traps focus within the given container
* @param container The container in which to trap focus
Expand Down Expand Up @@ -67,6 +86,8 @@ export function focusTrap(
container.prepend(sentinelStart)
container.append(sentinelEnd)

const observer = observeFocusTrap(container, [sentinelStart, sentinelEnd])

let lastFocusedChild: HTMLElement | undefined = undefined
// Ensure focus remains in the trap zone by checking that a given recently-focused
// element is inside the trap zone. If it isn't, redirect focus to a suitable
Expand Down Expand Up @@ -117,6 +138,7 @@ export function focusTrap(
if (suspendedTrapIndex >= 0) {
suspendedTrapStack.splice(suspendedTrapIndex, 1)
}
observer.disconnect()
tryReactivate()
})

Expand Down

0 comments on commit 04fa6a8

Please sign in to comment.