mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-15 19:10:47 +02:00
# Description of Changes Move frontend code into `core` folder and add infrastructure for `proprietary` folder to include premium, non-OSS features
77 lines
2.0 KiB
TypeScript
77 lines
2.0 KiB
TypeScript
import { useEffect, RefObject } from 'react';
|
|
|
|
const FOCUSABLE_ELEMENTS = [
|
|
'a[href]',
|
|
'button:not([disabled])',
|
|
'input:not([disabled])',
|
|
'select:not([disabled])',
|
|
'textarea:not([disabled])',
|
|
'[tabindex]:not([tabindex="-1"])',
|
|
].join(', ');
|
|
|
|
export function useFocusTrap(containerRef: RefObject<HTMLElement | null>, enabled: boolean = true) {
|
|
useEffect(() => {
|
|
if (!enabled || !containerRef.current) {
|
|
return;
|
|
}
|
|
|
|
const container = containerRef.current;
|
|
const getFocusableElements = () =>
|
|
Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE_ELEMENTS));
|
|
|
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
if (event.key !== 'Tab') {
|
|
return;
|
|
}
|
|
|
|
const focusableElements = getFocusableElements();
|
|
if (focusableElements.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const firstElement = focusableElements[0];
|
|
const lastElement = focusableElements[focusableElements.length - 1];
|
|
const activeElement = document.activeElement as HTMLElement;
|
|
|
|
// Check if focus is within the container
|
|
if (!container.contains(activeElement)) {
|
|
event.preventDefault();
|
|
firstElement.focus();
|
|
return;
|
|
}
|
|
|
|
// Shift + Tab (backwards)
|
|
if (event.shiftKey) {
|
|
if (activeElement === firstElement) {
|
|
event.preventDefault();
|
|
lastElement.focus();
|
|
}
|
|
}
|
|
// Tab (forwards)
|
|
else {
|
|
if (activeElement === lastElement) {
|
|
event.preventDefault();
|
|
firstElement.focus();
|
|
}
|
|
}
|
|
};
|
|
|
|
// Focus first element on mount
|
|
const focusableElements = getFocusableElements();
|
|
if (focusableElements.length > 0) {
|
|
// Small delay to ensure the element is fully rendered
|
|
setTimeout(() => {
|
|
focusableElements[0]?.focus();
|
|
}, 100);
|
|
}
|
|
|
|
document.addEventListener('keydown', handleKeyDown);
|
|
|
|
return () => {
|
|
document.removeEventListener('keydown', handleKeyDown);
|
|
};
|
|
}, [containerRef, enabled]);
|
|
}
|
|
|
|
|