/** Sequentially focusable descendants in DOM order, including in DOM test shims. */ export function focusableElements(container: Element): HTMLElement[] { return Array.from(container.querySelectorAll( 'button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [href], [tabindex]:not([tabindex="-1"])', )).filter(element => element.tabIndex >= 0 && element.getAttribute('type') !== 'hidden' && !element.closest('[hidden], [inert], [aria-hidden="true"]')) .sort((a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1) } /** App popups are portaled; DOM order alone may disagree with their overlay z-index. */ export function topmostDialog(): HTMLElement | undefined { const dialogs = document.querySelectorAll('[role="dialog"]') let top: HTMLElement | undefined let highest = -Infinity for (const dialog of dialogs) { let layer = 0 for (let element: HTMLElement | null = dialog; element; element = element.parentElement) { const z = Number.parseInt(getComputedStyle(element).zIndex, 10) if (Number.isFinite(z)) layer = Math.max(layer, z) } // Later DOM order wins only when overlay layers are equal. if (layer >= highest) { top = dialog; highest = layer } } return top }