콘텐츠의 선형 구조
This commit is contained in:
@@ -136,11 +136,14 @@ export function Header({
|
||||
authService,
|
||||
tokenManager,
|
||||
viewOnly,
|
||||
showSidebarTrigger = true,
|
||||
}: {
|
||||
authService?: AuthService;
|
||||
/** @deprecated authService를 사용하세요. */
|
||||
tokenManager?: TokenManager;
|
||||
viewOnly?: boolean;
|
||||
/** false 이면 LNB 토글 버튼을 헤더에 렌더링하지 않고 같은 크기의 자리만 유지 (BaseLayout 이 LNB 바로 앞에 렌더링) */
|
||||
showSidebarTrigger?: boolean;
|
||||
}) {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [logoWidth, setLogoWidth] = useState(0);
|
||||
@@ -276,7 +279,11 @@ export function Header({
|
||||
>
|
||||
<div className="flex w-full items-center justify-between px-2 sm:w-auto sm:justify-start sm:px-4 md:px-6">
|
||||
<div className="flex items-center gap-2 sm:gap-4">
|
||||
<SidebarTrigger className="size-12 !bg-transparent p-2 hover:!bg-accent [&>svg]:!size-full [&>svg]:text-foreground" />
|
||||
{showSidebarTrigger ? (
|
||||
<SidebarTrigger className="size-12 !bg-transparent p-2 hover:!bg-accent [&>svg]:!size-full [&>svg]:text-foreground" />
|
||||
) : (
|
||||
<span aria-hidden="true" className="size-12 shrink-0" />
|
||||
)}
|
||||
<h1>
|
||||
{/* 로고·사이트명 클릭 시 메인으로 이동 */}
|
||||
<a
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { QueryClient } from "@tanstack/react-query";
|
||||
import { QueryProvider } from "../../provider/query-provider";
|
||||
import { PopupProvider } from "../../provider/popup-provider";
|
||||
import type { MenuItem } from "../../api";
|
||||
import { SidebarProvider } from "../sidebar";
|
||||
import { SidebarProvider, SidebarTrigger } from "../sidebar";
|
||||
import { LNB } from "../lnb";
|
||||
import { Header } from "../header";
|
||||
import { Footer } from "../footer";
|
||||
@@ -17,6 +17,7 @@ export function BaseLayout({
|
||||
tokenManager,
|
||||
currentPath,
|
||||
handleMenuClick,
|
||||
sidebarTriggerPlacement = "header",
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
queryClient?: QueryClient;
|
||||
@@ -25,7 +26,15 @@ export function BaseLayout({
|
||||
tokenManager?: TokenManager;
|
||||
currentPath?: string;
|
||||
handleMenuClick?: (item: MenuItem) => void;
|
||||
/**
|
||||
* LNB 토글 버튼의 DOM 위치.
|
||||
* - "header": 헤더 로고(h1) 앞 (기존)
|
||||
* - "lnb": LNB 바로 앞 (콘텐츠 선형 구조 준수). 화면 위치는 CSS 로 헤더 좌측에 동일하게 유지
|
||||
*/
|
||||
sidebarTriggerPlacement?: "header" | "lnb";
|
||||
}) {
|
||||
const isTriggerBeforeLnb = sidebarTriggerPlacement === "lnb";
|
||||
|
||||
return (
|
||||
<QueryProvider queryClient={queryClient}>
|
||||
<PopupProvider>
|
||||
@@ -35,7 +44,15 @@ export function BaseLayout({
|
||||
<Header
|
||||
authService={authService}
|
||||
tokenManager={authService ? undefined : tokenManager}
|
||||
showSidebarTrigger={!isTriggerBeforeLnb}
|
||||
/>
|
||||
{/* 접기/펼치기 버튼을 제어 대상(LNB) 바로 앞에 배치하고, 화면에서는 헤더 좌측(기존 위치)에 고정 */}
|
||||
{isTriggerBeforeLnb && (
|
||||
<SidebarTrigger
|
||||
aria-controls="lnb"
|
||||
className="fixed left-2 top-0 z-40 size-12 !bg-transparent p-2 hover:!bg-accent [&>svg]:!size-full [&>svg]:text-foreground sm:left-4 sm:top-[1.5rem] md:left-6"
|
||||
/>
|
||||
)}
|
||||
<div className="flex">
|
||||
<LNB
|
||||
currentPath={currentPath}
|
||||
|
||||
Reference in New Issue
Block a user