New

SidebarNav

Collapsible sidebar with icon-only collapsed mode, section headers, active states with blue highlight, and badge counts.

Navigation & Layoutsidebarnavigationcollapsiblelayout

Dependencies

shadcn/ui components needed:

npx shadcn@latest add buttonnpx shadcn@latest add badgenpx shadcn@latest add separatornpx shadcn@latest add tooltip

How to use this component

Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.

Code

1"use client";
2
3import { useState } from 'react';
4import { Home, FolderOpen, Settings, ChevronLeft, ChevronRight, Users, BarChart3, Bell } from 'lucide-react';
5import { Button } from '@/components/ui/button';
6import { Badge } from '@/components/ui/badge';
7import { Separator } from '@/components/ui/separator';
8import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
9
10export default function SidebarNav() {
11 const [collapsed, setCollapsed] = useState(false);
12
13 const navItems = [
14 { section: 'Main', items: [
15 { icon: Home, label: 'Dashboard', active: true, badge: null },
16 { icon: BarChart3, label: 'Analytics', active: false, badge: '3' },
17 { icon: Users, label: 'Team', active: false, badge: null },
18 { icon: Bell, label: 'Notifications', active: false, badge: '12' },
19 ]},
20 { section: 'Projects', items: [
21 { icon: FolderOpen, label: 'All Projects', active: false, badge: '8' },
22 { icon: FolderOpen, label: 'Recent', active: false, badge: null },
23 ]},
24 { section: 'Settings', items: [
25 { icon: Settings, label: 'Settings', active: false, badge: null },
26 ]},
27 ];
28
29 const NavItem = ({ icon: Icon, label, active, badge }: any) => {
30 const content = (
31 <div className={`flex items-center gap-3 w-full px-3 py-2.5 rounded-lg transition-all duration-200 ${active ? 'bg-blue-500/10 text-blue-600 dark:text-blue-400' : 'text-slate-600 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-800'}`}>
32 <Icon className="w-5 h-5 flex-shrink-0" />
33 {!collapsed && (
34 <>
35 <span className={`font-medium ${active ? 'text-blue-600 dark:text-blue-400' : ''}`}>{label}</span>
36 {badge && <Badge variant="secondary" className="ml-auto bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300">{badge}</Badge>}
37 </>
38 )}
39 </div>
40 );
41
42 if (collapsed) {
43 return (
44 <TooltipProvider>
45 <Tooltip>
46 <TooltipTrigger asChild>{content}</TooltipTrigger>
47 <TooltipContent side="right">{label}</TooltipContent>
48 </Tooltip>
49 </TooltipProvider>
50 );
51 }
52 return content;
53 };
54
55 return (
56 <div className={`h-full bg-white dark:bg-slate-950 border-r border-slate-200 dark:border-slate-800 transition-all duration-300 ${collapsed ? 'w-16' : 'w-64'}`}>
57 <div className="flex flex-col h-full">
58 <div className="flex items-center justify-between p-4">
59 {!collapsed && <span className="font-bold text-lg text-slate-900 dark:text-white">Navigation</span>}
60 <Button variant="ghost" size="icon" onClick={() => setCollapsed(!collapsed)} className="ml-auto">
61 {collapsed ? <ChevronRight className="w-4 h-4" /> : <ChevronLeft className="w-4 h-4" />}
62 </Button>
63 </div>
64 <Separator />
65 <div className="flex-1 overflow-y-auto py-4 px-2">
66 {navItems.map((section, idx) => (
67 <div key={idx} className="mb-4">
68 {!collapsed && <span className="px-3 mb-2 text-xs font-semibold text-slate-500 dark:text-slate-500 uppercase tracking-wider">{section.section}</span>}
69 {section.items.map((item, itemIdx) => (
70 <NavItem key={itemIdx} {...item} />
71 ))}
72 {idx < navItems.length - 1 && <Separator className="my-3" />}
73 </div>
74 ))}
75 </div>
76 </div>
77 </div>
78 );
79}

Related Navigation & Layout Components

Command Palette

Search for a command to run...