export default function (elm: HTMLElement, targetElm: Element, forceFirst: boolean = false): void {
const walker = createFocusWalker(elm);
const position = targetElm.compareDocumentPosition(elm);
let wrappedTarget: HTMLElement | null;
if ((position & Node.DOCUMENT_POSITION_PRECEDING) !== 0 || forceFirst) {
wrappedTarget = walker.firstChild() as HTMLElement | null;
} else {
wrappedTarget = walker.lastChild() as HTMLElement | null;
}
const newFocus = wrappedTarget !== null ? wrappedTarget : elm;
newFocus.focus();
}
function createFocusWalker(elm: HTMLElement): TreeWalker {
return document.createTreeWalker(elm, NodeFilter.SHOW_ELEMENT, {
acceptNode: (node: HTMLButtonElement) => node.tabIndex >= 0 && !node.disabled ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP
});
}