@redocly/theme
Version:
Shared UI components lib
40 lines (31 loc) • 1.18 kB
text/typescript
import { useEffect } from 'react';
import type { RefObject } from 'react';
export function useFocusTrap(containerRef: RefObject<HTMLElement | null>): void {
useEffect(() => {
const trapElement = containerRef.current;
if (!trapElement) return;
const focusableElements = trapElement.querySelectorAll<HTMLElement>(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
);
const firstElement = focusableElements[0];
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Tab') {
const lastElement = focusableElements[focusableElements.length - 1];
if (event.shiftKey && document.activeElement === firstElement) {
lastElement?.focus();
event.preventDefault();
} else if (!event.shiftKey && document.activeElement === lastElement) {
firstElement?.focus();
event.preventDefault();
}
}
};
trapElement.addEventListener('keydown', handleKeyDown);
if (firstElement) {
firstElement.focus();
}
return () => {
trapElement.removeEventListener('keydown', handleKeyDown);
};
}, [containerRef]);
}