+
-
{children}
+
+ {children}
+
diff --git a/packages/common/components/src/ui/layout/skip-navigation.tsx b/packages/common/components/src/ui/layout/skip-navigation.tsx
new file mode 100644
index 000000000..9313b1d8f
--- /dev/null
+++ b/packages/common/components/src/ui/layout/skip-navigation.tsx
@@ -0,0 +1,59 @@
+"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
) => {
+ 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 (
+
+ );
+}
diff --git a/packages/common/components/src/ui/layout/vbase.tsx b/packages/common/components/src/ui/layout/vbase.tsx
index 7868a412f..d855d0cd9 100644
--- a/packages/common/components/src/ui/layout/vbase.tsx
+++ b/packages/common/components/src/ui/layout/vbase.tsx
@@ -3,6 +3,7 @@ import { SidebarProvider } from "../sidebar";
import { LNB } from "../lnb";
import { Header } from "../header";
import { Footer } from "../footer";
+import { SkipNavigation } from "./skip-navigation";
import "./common.css";
import type { QueryClient } from "@tanstack/react-query";
@@ -18,13 +19,18 @@ export function VBaseLayout({
+
diff --git a/packages/common/components/src/ui/lnb/index.tsx b/packages/common/components/src/ui/lnb/index.tsx
index 99c7402d7..cdfb51f32 100644
--- a/packages/common/components/src/ui/lnb/index.tsx
+++ b/packages/common/components/src/ui/lnb/index.tsx
@@ -187,7 +187,6 @@ export function LNB({
}) {
const {
open: isSidebarOpen,
- setOpen,
isMobile: isMobileView,
setOpenMobile: closeMobileSidebar,
} = useSidebar();
@@ -348,6 +347,10 @@ export function LNB({
)}
>