ChatGPT와 Next.js 공부

Next.js 레이아웃에서 Side Drawer(사이드바)를 토글

그랜파 개발자 2025. 5. 13. 08:14
sideDrawer를 숨길 수 있도록 해줘.
 

ChatGPT의 말:

Side Drawer(사이드바)를 토글하여 숨기거나 보이도록 하려면 상태(state)와 버튼을 사용하여 구현할 수 있습니다. 아래는 Next.js (App Router 기반) + Tailwind CSS를 사용하는 기본 레이아웃에서 Side Drawer를 열고 닫을 수 있도록 구성한 예시입니다.

🔧 1. 폴더 구조 예시 (app 기반)

app/
  layout.tsx
  globals.css
  page.tsx
components/
  AppBar.tsx
  SideDrawer.tsx
  Footer.tsx

📁 components/AppBar.tsx

'use client';

type Props = {
  onToggleDrawer: () => void;
};

export default function AppBar({ onToggleDrawer }: Props) {
  return (
    <header className="md:hidden flex items-center justify-between p-4 bg-white shadow">
      <button onClick={onToggleDrawer} className="text-xl">☰</button>
      <h1 className="font-bold text-lg">My App</h1>
    </header>
  );
}

📁 components/SideDrawer.tsx

'use client';

import Link from 'next/link';

type Props = {
  isOpen: boolean;
};

export default function SideDrawer({ isOpen }: Props) {
  return (
    <aside
      className={`fixed top-0 left-0 h-full w-64 bg-white shadow transform transition-transform duration-300 z-30
        ${isOpen ? 'translate-x-0' : '-translate-x-full'}
        md:translate-x-0 md:static md:block`}
    >
      <div className="p-4 font-bold text-xl border-b">My App</div>
      <nav className="p-4 space-y-2">
        <Link href="/" className="block text-gray-700 hover:text-blue-600">Home</Link>
        <Link href="/about" className="block text-gray-700 hover:text-blue-600">About</Link>
      </nav>
    </aside>
  );
}

📁 components/Footer.tsx

 
export default function Footer() {
  return (
    <footer className="p-4 text-center text-sm text-gray-500 border-t">
      © 2025 My App
    </footer>
  );
}

📁 app/layout.tsx

 
'use client';

import { useState } from 'react';
import './globals.css';
import AppBar from '@/components/AppBar';
import SideDrawer from '@/components/SideDrawer';
import Footer from '@/components/Footer';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const [isDrawerOpen, setDrawerOpen] = useState(false);

  return (
    <html lang="en">
      <body className="flex min-h-screen bg-gray-100">
        <SideDrawer isOpen={isDrawerOpen} />

        <div className="flex-1 ml-0 md:ml-64">
          <AppBar onToggleDrawer={() => setDrawerOpen(!isDrawerOpen)} />

          <main className="p-6">{children}</main>

          <Footer />
        </div>
      </body>
    </html>
  );
}

✅ 결과

  • 컴포넌트 분리로 재사용성과 유지보수성 향상
  • SideDrawer는 모바일에서 숨기고 토글 가능
  • AppBar, Footer가 독립적으로 관리됨