Files
CapaKraken/apps/web/src/hooks/useFocusTrap.ts
T

32 lines
1.1 KiB
TypeScript

import { useEffect } from "react";
const FOCUSABLE_SELECTOR =
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
export function useFocusTrap(ref: React.RefObject<HTMLElement | null>, isOpen: boolean) {
useEffect(() => {
if (!isOpen || !ref.current) return;
const el = ref.current;
const focusable = Array.from(el.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR));
const first = focusable[0];
const last = focusable[focusable.length - 1];
// Focus first element when modal opens
first?.focus();
function handleKeyDown(e: KeyboardEvent) {
if (e.key !== "Tab") return;
if (focusable.length === 0) { e.preventDefault(); return; }
if (e.shiftKey) {
if (document.activeElement === first) { e.preventDefault(); last?.focus(); }
} else {
if (document.activeElement === last) { e.preventDefault(); first?.focus(); }
}
}
el.addEventListener("keydown", handleKeyDown);
return () => el.removeEventListener("keydown", handleKeyDown);
}, [isOpen, ref]);
}