chore(repo): initialize planarchy workspace
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
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]);
|
||||
}
|
||||
Reference in New Issue
Block a user