Project: Collapsible Sidebar Navigation
In this project, we will construct a collapsible administrative sidebar component. The component supports toggleable expanded states and highlights active menu items using Lucide icons.
1. Sidebar Specifications
- Expanded State: Displays full menu text alongside icons.
- Collapsed State: Shrinks to a narrow column showing only the icons.
- Tooltips: Shows menu titles on hover when the sidebar is collapsed.
2. Implementing the React Component
Here is the React component code. Save this inside src/components/Sidebar.tsx:
import React, { useState } from "react";
import {
Home,
BarChart2,
Settings,
ChevronLeft,
ChevronRight,
Users
} from "lucide-react";
interface MenuItem {
title: string;
icon: React.ComponentType<{ className?: string }>;
active: boolean;
}
export function Sidebar() {
const [isExpanded, setIsExpanded] = useState(true);
const menuItems: MenuItem[] = [
{ title: "Dashboard", icon: Home, active: true },
{ title: "Analytics", icon: BarChart2, active: false },
{ title: "Team Members", icon: Users, active: false },
{ title: "Configuration", icon: Settings, active: false },
];
return (
<aside
className={`min-h-screen bg-slate-900 text-slate-100 flex flex-col transition-all duration-300 border-r border-slate-800 ${
isExpanded ? "w-64" : "w-20"
}`}
>
{/* 1. Header with Collapse Toggle button */}
<div className="h-16 flex items-center justify-between px-4 border-b border-slate-800">
{isExpanded && <span className="font-bold text-lg">Admin Panel</span>}
<button
onClick={() => setIsExpanded(!isExpanded)}
className="p-1.5 rounded-lg bg-slate-800 hover:bg-slate-700 transition mx-auto md:mx-0"
>
{isExpanded ? <ChevronLeft className="w-5 h-5" /> : <ChevronRight className="w-5 h-5" />}
</button>
</div>
{/* 2. Menu Items Navigation Links */}
<nav className="flex-1 p-3 space-y-2 mt-4">
{menuItems.map((item, index) => {
const Icon = item.icon;
return (
<a
key={index}
href="#"
className={`flex items-center gap-4 px-4 py-3 rounded-xl transition-all group relative ${
item.active
? "bg-blue-600 text-white font-semibold"
: "text-slate-400 hover:bg-slate-800 hover:text-white"
}`}
>
{/* Icon */}
<Icon className="w-5 h-5 shrink-0" />
{/* Text Label (Hidden if sidebar collapsed) */}
{isExpanded ? (
<span className="truncate">{item.title}</span>
) : (
/* Simple CSS Tooltip for collapsed mode */
<span className="absolute left-16 scale-0 group-hover:scale-100 transition-all bg-slate-950 text-white text-xs px-2.5 py-1.5 rounded-md border border-slate-800 shadow-md z-30 whitespace-nowrap">
{item.title}
</span>
)}
</a>
);
})}
</nav>
{/* 3. Footer version stamp */}
<div className="p-4 border-t border-slate-800 text-xs text-slate-500 text-center">
{isExpanded ? "System Version 2.0" : "v2.0"}
</div>
</aside>
);
}This sidebar uses Tailwind conditional template classes (such as w-64 and w-20) to handle width transitions smoothly when the user toggles the collapse button.
Published on Last updated: