Profile page UI and functionality implemented
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"use client";
|
||||
|
||||
import type { RefObject } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
/**
|
||||
* Escape-to-close, body scroll lock, focus move-in and tab trap for Create-shell modals.
|
||||
*/
|
||||
export function useCreateModalA11y(
|
||||
isOpen: boolean,
|
||||
onClose: () => void,
|
||||
dialogRef: RefObject<HTMLDivElement | null>,
|
||||
): void {
|
||||
const previousActiveElementRef = useRef<HTMLElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
|
||||
const handleEscape = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", handleEscape);
|
||||
return () => {
|
||||
document.removeEventListener("keydown", handleEscape);
|
||||
};
|
||||
}, [isOpen, onClose]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
|
||||
previousActiveElementRef.current = document.activeElement as HTMLElement;
|
||||
document.body.style.overflow = "hidden";
|
||||
|
||||
if (dialogRef.current) {
|
||||
const focusableElements = dialogRef.current.querySelectorAll(
|
||||
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
|
||||
);
|
||||
const firstElement = focusableElements[0] as HTMLElement;
|
||||
if (firstElement) {
|
||||
firstElement.focus();
|
||||
} else {
|
||||
dialogRef.current.setAttribute("tabindex", "-1");
|
||||
dialogRef.current.focus();
|
||||
}
|
||||
}
|
||||
|
||||
const handleTab = (e: KeyboardEvent) => {
|
||||
if (e.key !== "Tab" || !dialogRef.current) return;
|
||||
|
||||
const focusableElements = dialogRef.current.querySelectorAll(
|
||||
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
|
||||
);
|
||||
const firstElement = focusableElements[0] as HTMLElement;
|
||||
const lastElement = focusableElements[
|
||||
focusableElements.length - 1
|
||||
] as HTMLElement;
|
||||
|
||||
if (e.shiftKey) {
|
||||
if (document.activeElement === firstElement) {
|
||||
e.preventDefault();
|
||||
lastElement?.focus();
|
||||
}
|
||||
} else {
|
||||
if (document.activeElement === lastElement) {
|
||||
e.preventDefault();
|
||||
firstElement?.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", handleTab);
|
||||
|
||||
return () => {
|
||||
document.body.style.overflow = "";
|
||||
document.removeEventListener("keydown", handleTab);
|
||||
previousActiveElementRef.current?.focus();
|
||||
};
|
||||
}, [isOpen]);
|
||||
}
|
||||
Reference in New Issue
Block a user