Sidebar
The Sidebar component provides navigation for documentation sites and dashboards. It supports responsive behavior, collapsible sections, and various styling options.
Basic Usage
import { Sidebar } from "@/components/docs/Sidebar"
const navigation = [
{
title: "Getting Started",
items: [
{
title: "Introduction",
href: "/docs/introduction",
},
{
title: "Installation",
href: "/docs/installation",
},
],
},
{
title: "Components",
items: [
{
title: "Button",
href: "/docs/components/button",
},
],
},
]
<Sidebar items={navigation} />
Component Implementation
Here’s a basic implementation of the Sidebar component:
// components/docs/Sidebar.tsx
import { cn } from "@/lib/utils"
import { useState } from "react"
import { ChevronDown } from "lucide-react"
interface SidebarProps {
items: {
title: string
items: {
title: string
href: string
}[]
}[]
className?: string
currentPath?: string
}
export function Sidebar({ items, className, currentPath }: SidebarProps) {
const [expanded, setExpanded] = useState<string[]>([])
const toggleSection = (title: string) => {
setExpanded(current =>
current.includes(title)
? current.filter(t => t !== title)
: [...current, title]
)
}
return (
<nav className={cn("w-full", className)}>
{items.map((section) => (
<div key={section.title} className="pb-4">
<button
onClick={() => toggleSection(section.title)}
className="flex w-full items-center justify-between px-2 py-1 text-sm font-semibold"
>
{section.title}
<ChevronDown
className={cn(
"h-4 w-4 transition-transform",
expanded.includes(section.title) && "rotate-180"
)}
/>
</button>
{expanded.includes(section.title) && (
<div className="grid grid-flow-row auto-rows-max text-sm">
{section.items.map((item) => (
<a
key={item.href}
href={item.href}
className={cn(
"flex w-full items-center rounded-md p-2 hover:underline",
currentPath === item.href && "bg-accent"
)}
>
{item.title}
</a>
))}
</div>
)}
</div>
))}
</nav>
)
}
With Icons
Add icons to sidebar items:
const navigationWithIcons = [
{
title: "Getting Started",
icon: <BookIcon className="h-4 w-4" />,
items: [
{
title: "Introduction",
href: "/docs/introduction",
icon: <FileTextIcon className="h-4 w-4" />,
},
],
},
]
<Sidebar items={navigationWithIcons} />
Collapsible Sections
Implement collapsible sections with animation:
<div
className={cn(
"grid overflow-hidden transition-all",
expanded.includes(section.title)
? "grid-rows-[1fr]"
: "grid-rows-[0fr]"
)}
>
<div className="min-h-0">
{/* Section content */}
</div>
</div>
Mobile Navigation
Add a mobile navigation drawer:
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
import { Button } from "@/components/ui/button"
import { Menu } from "lucide-react"
export function MobileNav({ items }) {
return (
<Sheet>
<SheetTrigger asChild>
<Button variant="ghost" className="md:hidden">
<Menu className="h-6 w-6" />
</Button>
</SheetTrigger>
<SheetContent side="left" className="w-[300px] p-0">
<Sidebar items={items} className="p-6" />
</SheetContent>
</Sheet>
)
}
With Search
Add a search input to the sidebar:
<div className="sticky top-0 bg-background p-4 backdrop-blur">
<div className="relative">
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
<input
placeholder="Search..."
className="w-full rounded-md border pl-8 text-sm"
/>
</div>
</div>
Nested Navigation
Support multiple levels of navigation:
interface NestedItem {
title: string
href?: string
items?: NestedItem[]
}
function renderItems(items: NestedItem[], depth = 0) {
return items.map((item) => (
<div key={item.title} style={{ paddingLeft: `${depth * 12}px` }}>
{item.href ? (
<a href={item.href}>{item.title}</a>
) : (
<span>{item.title}</span>
)}
{item.items?.length && renderItems(item.items, depth + 1)}
</div>
))
}
Best Practices
-
Navigation Structure
- Keep hierarchy clear
- Limit nesting levels
- Group related items
-
Responsive Design
- Handle mobile views
- Consider tablet layouts
- Smooth transitions
-
Accessibility
- Keyboard navigation
- ARIA labels
- Focus management
-
State Management
- Remember expanded sections
- Highlight current page
- Handle deep linking
-
Performance
- Optimize animations
- Lazy load content
- Cache expanded state
-
Visual Design
- Clear visual hierarchy
- Consistent spacing
- Proper indentation