mirror of
https://github.com/priyanshujain/margin.git
synced 2026-10-02 19:17:03 +00:00
group of bug fixes
This commit is contained in:
1 parent
cfc93fc97d
commit
bcd5eb9ebc
30 files changed
+973
-238
No files matched your search
@@ -0,0 +1,56 @@
|
||||
import { useEffect, useRef, type RefObject } from "react";
|
||||
|
||||
const FOCUSABLE =
|
||||
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
||||
|
||||
function focusable(root: HTMLElement): HTMLElement[] {
|
||||
return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE)).filter(
|
||||
(el) => !el.hidden && el.offsetParent !== null,
|
||||
);
|
||||
}
|
||||
|
||||
let openTraps = 0;
|
||||
|
||||
export function focusTrapped(): boolean {
|
||||
return openTraps > 0;
|
||||
}
|
||||
|
||||
export function useFocusTrap(ref: RefObject<HTMLElement | null>, active = true): void {
|
||||
const opener = useRef<HTMLElement | null>(null);
|
||||
const wasActive = useRef(false);
|
||||
if (active && !wasActive.current) opener.current = document.activeElement as HTMLElement | null;
|
||||
wasActive.current = active;
|
||||
|
||||
useEffect(() => {
|
||||
const root = ref.current;
|
||||
if (!active || !root) return;
|
||||
openTraps++;
|
||||
if (!root.contains(document.activeElement)) focusable(root)[0]?.focus();
|
||||
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key !== "Tab") return;
|
||||
const items = focusable(root);
|
||||
if (!items.length) return;
|
||||
const first = items[0];
|
||||
const last = items[items.length - 1];
|
||||
const current = document.activeElement as HTMLElement | null;
|
||||
if (!current || !root.contains(current)) {
|
||||
e.preventDefault();
|
||||
(e.shiftKey ? last : first).focus();
|
||||
} else if (e.shiftKey && current === first) {
|
||||
e.preventDefault();
|
||||
last.focus();
|
||||
} else if (!e.shiftKey && current === last) {
|
||||
e.preventDefault();
|
||||
first.focus();
|
||||
}
|
||||
};
|
||||
|
||||
root.addEventListener("keydown", onKeyDown);
|
||||
return () => {
|
||||
openTraps--;
|
||||
root.removeEventListener("keydown", onKeyDown);
|
||||
if (opener.current?.isConnected) opener.current.focus();
|
||||
};
|
||||
}, [ref, active]);
|
||||
}
|
||||
Reference in new issue
Block a user