60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
import { useSidebar } from "../sidebar";
|
|
|
|
type SkipNavigationProps = {
|
|
includeLnb?: boolean;
|
|
};
|
|
|
|
const linkClassName =
|
|
"sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[100] focus:rounded-sm focus:bg-background focus:px-4 focus:py-3 focus:text-foreground focus:shadow-lg focus:outline focus:outline-2 focus:outline-primary";
|
|
|
|
export function SkipNavigation({
|
|
includeLnb = true,
|
|
}: SkipNavigationProps) {
|
|
const { isMobile, open, openMobile, setOpen, setOpenMobile } = useSidebar();
|
|
const shouldFocusLnb = useRef(false);
|
|
|
|
useEffect(() => {
|
|
const isLnbOpen = isMobile ? openMobile : open;
|
|
if (!shouldFocusLnb.current || !isLnbOpen) return;
|
|
|
|
document.getElementById("lnb")?.focus();
|
|
shouldFocusLnb.current = false;
|
|
}, [isMobile, open, openMobile]);
|
|
|
|
const handleLnbClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
|
|
event.preventDefault();
|
|
const isLnbOpen = isMobile ? openMobile : open;
|
|
|
|
if (isLnbOpen) {
|
|
document.getElementById("lnb")?.focus();
|
|
return;
|
|
}
|
|
|
|
shouldFocusLnb.current = true;
|
|
if (isMobile) {
|
|
setOpenMobile(true);
|
|
} else {
|
|
setOpen(true);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<nav aria-label="건너뛰기">
|
|
<a className={linkClassName} href="#main-content">
|
|
본문 바로가기
|
|
</a>
|
|
<a className={linkClassName} href="#gnb">
|
|
주메뉴 바로가기
|
|
</a>
|
|
{includeLnb && (
|
|
<a className={linkClassName} href="#lnb" onClick={handleLnbClick}>
|
|
부메뉴 바로가기
|
|
</a>
|
|
)}
|
|
</nav>
|
|
);
|
|
}
|