export type DialogFocusFallback = () => HTMLElement | null;
type DialogFocusTarget = HTMLElement | null;
function isUsableFocusTarget(target: DialogFocusTarget): target is HTMLElement {
const ownerDocument = target?.ownerDocument;
return Boolean(
target?.isConnected &&
ownerDocument &&
target !== ownerDocument.body &&
target !== ownerDocument.documentElement,
);
}
/**
* Return focus to the control that opened a dialog while it still exists. If a
* successful action removed that control, move focus to a persistent settings
* target instead of leaving it on the document body.
*/
export function restoreDialogFocus(
previouslyFocused: HTMLElement | null,
getFallback?: DialogFocusFallback,
): void {
let target = previouslyFocused;
if (!isUsableFocusTarget(target)) {
target = getFallback?.() ?? null;
}
if (!isUsableFocusTarget(target)) {
return;
}
target.focus({ preventScroll: true });
}