Menu
popagent
publicLatest change da13a7bebe63bf4b2693180d2d4850aabeaa0807 - Add autonomous evolution and self-healing by AkurAI Build
import { useEffect, type RefObject } from "react";
const FOCUSABLE = 'a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])';
/** Trap Tab focus inside `ref` while `active`; restore focus to the prior element on release. */
export function useFocusTrap(ref: RefObject<HTMLElement | null>, active: boolean): void {
useEffect(() => {
if (!active) return;
const container = ref.current;
if (!container) return;
const previous = document.activeElement as HTMLElement | null;
const trap = (event: KeyboardEvent) => {
if (event.key !== "Tab") return;
const nestedModal = container.querySelector<HTMLElement>('[aria-modal="true"]');
if (nestedModal?.contains(document.activeElement)) return;
const focusable = Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE))
.filter((element) => element.offsetParent !== null || element === document.activeElement);
if (!focusable.length) return;
const first = focusable[0]!;
const last = focusable[focusable.length - 1]!;
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first.focus();
}
};
document.addEventListener("keydown", trap);
return () => {
document.removeEventListener("keydown", trap);
previous?.focus?.();
};
}, [ref, active]);
}