@coin-voyage/paykit
Version:
Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.
62 lines • 2.06 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
// Based on https://hiddedevries.nl/en/blog/2017-01-29-using-javascript-to-trap-focus-in-an-element
import { useEffect, useRef } from "react";
const KEYCODE_TAB = 9;
function useFocusTrap() {
const elRef = useRef(null);
function handleFocus(e) {
if (!elRef.current) {
return;
}
const focusableEls = elRef.current.querySelectorAll(`
a[href]:not(:disabled),
button:not(:disabled),
textarea:not(:disabled),
input[type="text"]:not(:disabled),
input[type="radio"]:not(:disabled),
input[type="checkbox"]:not(:disabled),
select:not(:disabled)
`);
const firstFocusableEl = focusableEls[0];
const lastFocusableEl = focusableEls[focusableEls.length - 1];
const isTabPressed = e.key === "Tab" || e.keyCode === KEYCODE_TAB;
if (!isTabPressed) {
return;
}
if (e.shiftKey) {
/* shift + tab */ if (document.activeElement === firstFocusableEl) {
lastFocusableEl.focus();
e.preventDefault();
}
} /* tab */
else {
if (document.activeElement === lastFocusableEl) {
firstFocusableEl.focus();
e.preventDefault();
}
}
}
useEffect(() => {
if (elRef.current) {
elRef.current.addEventListener("keydown", handleFocus);
elRef.current.focus({ preventScroll: true });
}
return () => {
if (elRef.current) {
elRef.current.removeEventListener("keydown", handleFocus);
}
};
}, []);
return elRef;
}
export default function FocusTrap(props) {
const elRef = useFocusTrap();
useEffect(() => {
if (!elRef.current) {
return;
}
elRef.current.focus({ preventScroll: true });
}, []);
return _jsx("div", { ref: elRef, children: props.children });
}
//# sourceMappingURL=useFocusTrap.js.map