Sidebarstandard
앱 왼쪽(또는 오른쪽)에 붙는 내비게이션 사이드바(sidebar)입니다. shadcn base-nova 의 stock 아이템입니다. 데스크톱에서는 접고 펼 수 있는 고정 패널로, 모바일에서는 `sheet` 로 열리는 패널로 그립니다.
설치
pnpm
pnpm dlx shadcn@4.23.0 add @uikit/sidebarDefault
sidebar-example.tsx
"use client"
import * as React from "react"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger,} from "@/components/ui/dropdown-menu"import { Item, ItemActions, ItemContent, ItemDescription, ItemTitle,} from "@/components/ui/item"import { Label } from "@/components/ui/label"import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarRail, SidebarTrigger,} from "@/components/ui/sidebar"import { CheckIcon, ChevronsUpDownIcon, SearchIcon } from "lucide-react"
export default function SidebarExample() { const data = { versions: ["1.0.1", "1.1.0-alpha", "2.0.0-beta1"], navMain: [ { title: "Getting Started", url: "#", items: [ { title: "Installation", url: "#", }, { title: "Project Structure", url: "#", }, ], }, { title: "Build Your Application", url: "#", items: [ { title: "Routing", url: "#", }, { title: "Data Fetching", url: "#", isActive: true, }, { title: "Rendering", url: "#", }, { title: "Caching", url: "#", }, { title: "Styling", url: "#", }, { title: "Optimizing", url: "#", }, { title: "Configuring", url: "#", }, { title: "Testing", url: "#", }, { title: "Authentication", url: "#", }, { title: "Deploying", url: "#", }, { title: "Upgrading", url: "#", }, { title: "Examples", url: "#", }, ], }, { title: "API Reference", url: "#", items: [ { title: "Components", url: "#", }, { title: "File Conventions", url: "#", }, { title: "Functions", url: "#", }, { title: "next.config.js Options", url: "#", }, { title: "CLI", url: "#", }, { title: "Edge Runtime", url: "#", }, ], }, { title: "Architecture", url: "#", items: [ { title: "Accessibility", url: "#", }, { title: "Fast Refresh", url: "#", }, { title: "Next.js Compiler", url: "#", }, { title: "Supported Browsers", url: "#", }, { title: "Turbopack", url: "#", }, ], }, ], }
const [selectedVersion, setSelectedVersion] = React.useState(data.versions[0])
return ( <SidebarProvider> <Sidebar> <SidebarHeader> <SidebarMenu> <SidebarMenuItem> <DropdownMenu> <DropdownMenuTrigger render={ <SidebarMenuButton size="lg" className="data-open:bg-sidebar-accent data-open:text-sidebar-accent-foreground" /> } > <Item className="p-0" size="xs"> <ItemContent> <ItemTitle className="text-sm">Documentation</ItemTitle> <ItemDescription>v{selectedVersion}</ItemDescription> </ItemContent> <ItemActions> <ChevronsUpDownIcon /> </ItemActions> </Item> </DropdownMenuTrigger> <DropdownMenuContent> {data.versions.map((version) => ( <DropdownMenuItem key={version} onSelect={() => setSelectedVersion(version)} > v{version}{" "} {version === selectedVersion && ( <CheckIcon className="ml-auto" /> )} </DropdownMenuItem> ))} </DropdownMenuContent> </DropdownMenu> </SidebarMenuItem> </SidebarMenu> <form> <SidebarGroup className="py-0"> <SidebarGroupContent className="relative"> <Label htmlFor="search" className="sr-only"> Search </Label> <SidebarInput id="search" placeholder="Search the docs..." className="pl-8" /> <SearchIcon className="pointer-events-none absolute top-1/2 left-2 size-4 -translate-y-1/2 opacity-50 select-none" /> </SidebarGroupContent> </SidebarGroup> </form> </SidebarHeader> <SidebarContent> {data.navMain.map((item) => ( <SidebarGroup key={item.title}> <SidebarGroupLabel>{item.title}</SidebarGroupLabel> <SidebarGroupContent> <SidebarMenu> {item.items.map((subItem) => ( <SidebarMenuItem key={subItem.title}> <SidebarMenuButton render={<a href={subItem.url} />} isActive={subItem.isActive} > {subItem.title} </SidebarMenuButton> </SidebarMenuItem> ))} </SidebarMenu> </SidebarGroupContent> </SidebarGroup> ))} </SidebarContent> <SidebarRail /> </Sidebar> <SidebarInset> <header className="flex h-16 shrink-0 items-center gap-2 px-4"> <SidebarTrigger className="-ml-1" /> </header> <div className="flex flex-1 flex-col gap-4 p-4"> <div className="grid auto-rows-min gap-4 md:grid-cols-3"> <div className="aspect-video rounded-xl bg-muted/50" /> <div className="aspect-video rounded-xl bg-muted/50" /> <div className="aspect-video rounded-xl bg-muted/50" /> </div> <div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" /> </div> </SidebarInset> </SidebarProvider> )}