@mantine/hooks
Version:
A collection of 50+ hooks for state and UI management
44 lines (43 loc) • 1.67 kB
JavaScript
"use client";
import { FOCUS_SELECTOR, focusable, tabbable } from "./tabbable.mjs";
import { scopeTab } from "./scope-tab.mjs";
import { useCallback, useEffect, useRef } from "react";
//#region packages/@mantine/hooks/src/use-focus-trap/use-focus-trap.ts
function useFocusTrap(active = true) {
const ref = useRef(null);
const focusNode = (node) => {
let focusElement = node.querySelector("[data-autofocus]");
if (!focusElement) {
const children = Array.from(node.querySelectorAll(FOCUS_SELECTOR));
focusElement = children.find(tabbable) || children.find(focusable) || null;
if (!focusElement && focusable(node)) focusElement = node;
}
if (focusElement) focusElement.focus({ preventScroll: true });
else console.warn("[@mantine/hooks/use-focus-trap] Failed to find focusable element within provided node", node);
};
const setRef = useCallback((node) => {
if (!active) return;
if (node === null) return;
if (ref.current === node) return;
if (node) {
setTimeout(() => {
if (node.getRootNode()) focusNode(node);
else console.warn("[@mantine/hooks/use-focus-trap] Ref node is not part of the dom", node);
});
ref.current = node;
} else ref.current = null;
}, [active]);
useEffect(() => {
if (!active) return;
ref.current && setTimeout(() => focusNode(ref.current));
const handleKeyDown = (event) => {
if (event.key === "Tab" && ref.current) scopeTab(ref.current, event);
};
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
}, [active]);
return setRef;
}
//#endregion
export { useFocusTrap };
//# sourceMappingURL=use-focus-trap.mjs.map