개요 Next.js 프로젝트에서 shadcn/ui를 사용해서, 반응형 사이드바를 쉽게 구현할 수 있다. 구현 방법 dashboard-02의 코드를 베이스로 구현하려고 한다. ※ 해당 컴포넌트에 대한 전체 코드: dashboard-02 패키지 설치 먼저, shadcn/ui를 설치한다. install shadcn/uinpx shadcn-ui@latest init 코드 복사 copy code버튼을 클릭해서, dashboard-02의 코드를 가져와서 app/page.tsx에 붙여넣어 준다. 컴포넌트 추가 아직 컴포넌트가 없으므로 오류가 생길 것이다. 아래 명령어로 컴포넌트를 추가한다. add componentsnpx shadcn-ui@latest add badge button card dropdown-menu input sheet 컴포넌트 분리 mobile navigation에 해당하는 부분을 components/ui에 mobile-nav.tsx 파일을 생성해서 옮겨준다. mobile-nav.tsximport Link from 'next/link'; import { Menu, Package2, Home, ShoppingCart, Package, Users, LineChart, } from 'lucide-react'; import { Button } from './button'; import { Card, CardHeader, CardTitle, CardDescription, CardContent, } from './card'; import { Sheet, SheetTrigger, SheetContent } from './sheet'; import { Badge } from './badge'; export default function MobileNav() { return ( <Sheet> <SheetTrigger asChild> <Button variant="outline" size="icon" className="shrink-0 md:hidden"> <Menu className="h-5 w-5" /> <span className="sr-only">Toggle navigation menu</span> </Button> </SheetTrigger> <SheetContent side="left" className="flex flex-col"> <nav className="grid gap-2 text-lg font-medium"> <Link href="#" className="flex items-center gap-2 text-lg font-semibold" > <Package2 className="h-6 w-6" /> <span className="sr-only">Acme Inc</span> </Link> <Link href="#" className="text-muted-foreground hover:text-foreground mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2" > <Home className="h-5 w-5" /> Dashboard </Link> <Link href="#" className="bg-muted text-foreground hover:text-foreground mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2" > <ShoppingCart className="h-5 w-5" /> Orders <Badge className="ml-auto flex h-6 w-6 shrink-0 items-center justify-center rounded-full"> 6 </Badge> </Link> <Link href="#" className="text-muted-foreground hover:text-foreground mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2" > <Package className="h-5 w-5" /> Products </Link> <Link href="#" className="text-muted-foreground hover:text-foreground mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2" > <Users className="h-5 w-5" /> Customers </Link> <Link href="#" className="text-muted-foreground hover:text-foreground mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2" > <LineChart className="h-5 w-5" /> Analytics </Link> </nav> <div className="mt-auto"> <Card> <CardHeader> <CardTitle>Upgrade to Pro</CardTitle> <CardDescription> Unlock all features and get unlimited access to our support team. </CardDescription> </CardHeader> <CardContent> <Button size="sm" className="w-full"> Upgrade </Button> </CardContent> </Card> </div> </SheetContent> </Sheet> ); } sidebar에 해당하는 부분을 components/ui에 sidebar.tsx 파일을 생성해서 옮겨준다. sidebar.tsximport Link from 'next/link'; import { Bell, Home, ShoppingCart, Package, Users, LineChart, Package2, } from 'lucide-react'; import { Button } from './button'; import { Badge } from './badge'; import { Card, CardHeader, CardTitle, CardDescription, CardContent, } from './card'; export default function Sidebar() { return ( <aside className="bg-muted/40 hidden border-r md:block"> <div className="flex h-full max-h-screen flex-col gap-2"> <div className="flex h-14 items-center border-b px-4 lg:h-[60px] lg:px-6"> <Link href="/" className="flex items-center gap-2 font-semibold"> <Package2 className="h-6 w-6" /> <span className="">Acme Inc</span> </Link> <Button variant="outline" size="icon" className="ml-auto h-8 w-8"> <Bell className="h-4 w-4" /> <span className="sr-only">Toggle notifications</span> </Button> </div> <div className="flex-1"> <nav className="grid items-start px-2 text-sm font-medium lg:px-4"> <Link href="#" className="text-muted-foreground flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary" > <Home className="h-4 w-4" /> Dashboard </Link> <Link href="#" className="text-muted-foreground flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary" > <ShoppingCart className="h-4 w-4" /> Orders <Badge className="ml-auto flex h-6 w-6 shrink-0 items-center justify-center rounded-full"> 6 </Badge> </Link> <Link href="#" className="bg-muted flex items-center gap-3 rounded-lg px-3 py-2 text-primary transition-all hover:text-primary" > <Package className="h-4 w-4" /> Products{' '} </Link> <Link href="#" className="text-muted-foreground flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary" > <Users className="h-4 w-4" /> Customers </Link> <Link href="#" className="text-muted-foreground flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary" > <LineChart className="h-4 w-4" /> Analytics </Link> </nav> </div> <div className="mt-auto p-4"> <Card x-chunk="dashboard-02-chunk-0"> <CardHeader className="p-2 pt-0 md:p-4"> <CardTitle>Upgrade to Pro</CardTitle> <CardDescription> Unlock all features and get unlimited access to our support team. </CardDescription> </CardHeader> <CardContent className="p-2 pt-0 md:p-4 md:pt-0"> <Button size="sm" className="w-full"> Upgrade </Button> </CardContent> </Card> </div> </div> </aside> ); } 코드 정리 사용하지 않는 부분에 대한 코드를 제거해준다. 예를 들어, 사이드바 하단의 Card 부분을 제거해준다. 중복되는 코드에 대해 컴포넌트를 생성해서 분리해준다. 네비게이션에 들어갈 목록은 화면 사이즈에 상관없이 동일하므로 이를 새로운 컴포넌트로 분리해준다. 구현 결과 아래 링크를 통해 정리된 소스 코드의 완성본을 확인할 수 있다. 완성된 소스 코드 참고: Youtube Link