mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 19:33:11 +02:00
Restructure frontend code to allow for extensions (#4721)
# Description of Changes Move frontend code into `core` folder and add infrastructure for `proprietary` folder to include premium, non-OSS features
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
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]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user