website refactor
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import React, {
|
||||
useEffect,
|
||||
useRef,
|
||||
type ReactNode,
|
||||
type KeyboardEvent as ReactKeyboardEvent,
|
||||
} from 'react';
|
||||
@@ -34,26 +32,6 @@ export function Modal({
|
||||
onOpenChange,
|
||||
isOpen,
|
||||
}: ModalProps) {
|
||||
const dialogRef = useRef<HTMLDivElement | null>(null);
|
||||
const previouslyFocusedElementRef = useRef<Element | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
previouslyFocusedElementRef.current = document.activeElement;
|
||||
const focusable = getFirstFocusable(dialogRef.current);
|
||||
if (focusable) {
|
||||
focusable.focus();
|
||||
} else if (dialogRef.current) {
|
||||
dialogRef.current.focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isOpen && previouslyFocusedElementRef.current instanceof HTMLElement) {
|
||||
previouslyFocusedElementRef.current.focus();
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
const handleKeyDown = (event: ReactKeyboardEvent<HTMLDivElement>) => {
|
||||
if (event.key === 'Escape') {
|
||||
if (onOpenChange) {
|
||||
@@ -61,26 +39,6 @@ export function Modal({
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.key === 'Tab') {
|
||||
const focusable = getFocusableElements(dialogRef.current);
|
||||
if (focusable.length === 0) return;
|
||||
|
||||
const first = focusable[0];
|
||||
const last = focusable[focusable.length - 1] ?? first;
|
||||
|
||||
if (!first || !last) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event.shiftKey && document.activeElement === last) {
|
||||
event.preventDefault();
|
||||
first.focus();
|
||||
} else if (event.shiftKey && document.activeElement === first) {
|
||||
event.preventDefault();
|
||||
last.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleBackdropClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
||||
@@ -104,7 +62,6 @@ export function Modal({
|
||||
onClick={handleBackdropClick}
|
||||
>
|
||||
<Box
|
||||
ref={dialogRef}
|
||||
style={{ width: '100%', maxWidth: '28rem', borderRadius: '1rem', backgroundColor: '#0f1115', border: '1px solid #262626', boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5)', outline: 'none' }}
|
||||
tabIndex={-1}
|
||||
>
|
||||
@@ -162,24 +119,3 @@ export function Modal({
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function getFocusableElements(root: HTMLElement | null): HTMLElement[] {
|
||||
if (!root) return [];
|
||||
const selectors = [
|
||||
'a[href]',
|
||||
'button:not([disabled])',
|
||||
'textarea:not([disabled])',
|
||||
'input:not([disabled])',
|
||||
'select:not([disabled])',
|
||||
'[tabindex]:not([tabindex="-1"])',
|
||||
];
|
||||
const nodes = Array.from(
|
||||
root.querySelectorAll<HTMLElement>(selectors.join(',')),
|
||||
);
|
||||
return nodes.filter((el) => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden'));
|
||||
}
|
||||
|
||||
function getFirstFocusable(root: HTMLElement | null): HTMLElement | null {
|
||||
const elements = getFocusableElements(root);
|
||||
return elements[0] ?? null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user