Sidebar
Overview
The Sidebar component is a versatile and animated navigation element that provides an elegant way to organize navigation links and actions in your application. It supports multiple positions, variants, and animations built with Framer Motion.
Preview
- Preview
- Code
Demo Window
Demo App
import { Sidebar } from './components/ui';
import { Home, User, Settings, HelpCircle } from 'lucide-react';
function SidebarDemo() {
const links = [
{ label: 'Home', href: '#', icon: Home },
{ label: 'Profile', href: '#', icon: User },
{ label: 'Settings', href: '#', icon: Settings },
{ label: 'Help', href: '#', icon: HelpCircle },
];
return (
<Sidebar
links={links}
brandName="Demo App"
/>
);
}
Installation
- npm
- yarn
- pnpm
- manual
npx @mindfiredigital/ignix-ui add sidebar
yarn @mindfiredigital/ignix-ui add sidebar
pnpm @mindfiredigital/ignix-ui add sidebar
import React, { useState } from "react";
import { motion } from "framer-motion";
import {
Menu,
X,
} from "lucide-react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "../../../utils/cn";
interface LinkItem {
label: string;
href: string;
icon: React.ElementType;
}
interface SidebarProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof sidebarVariants> {
links: LinkItem[];
brandName?: string;
position?: "left" | "right" | "bottomLeft" | "bottomRight";
onClose?: () => void;
}
const sidebarVariants = cva("absolute h-full overflow-hidden transition-all", {
variants: {
position: {
left: "top-0 left-0",
right: "top-0 right-0",
bottomLeft: "bottom-0 left-0",
bottomRight: "bottom-0 right-0",
},
isOpen: {
true: "w-64 h-full",
false: "w-20 h-full",
},
variant: {
default: "bg-background text-foreground",
dark: "bg-black text-white",
light: "bg-white text-gray-900 border-r",
glass: "bg-white/10 backdrop-blur-lg text-white",
},
direction: {
horizontal: "flex-row",
vertical: "flex-col items-start",
},
},
defaultVariants: {
position: "left",
isOpen: true,
variant: "default",
direction: "vertical",
},
});
const Sidebar: React.FC<SidebarProps> = ({
links,
brandName = "Brand",
position = "left",
onClose,
isOpen = true,
variant,
className,
direction,
}) => {
const [open, setOpen] = useState(isOpen);
const toggleSidebar = () => setOpen((prev) => !prev);
const handleClose = () => {
onClose?.();
};
return (
<motion.div
initial={{ x: 0 }}
animate={{ x: 0 }}
transition={{ duration: 0.4 }}
className={cn(
sidebarVariants({ position, isOpen: open, variant, direction }),
className
)}
>
{/* Sidebar Header */}
<div className="p-4 flex items-center justify-between gap-4">
{open && <h1 className="text-xl font-bold">{brandName}</h1>}
<button onClick={() => [toggleSidebar(), handleClose()]}>
{open ? (
<span title="Close">
<X size={24} />
</span>
) : (
<span title="Open">
<Menu size={24} />
</span>
)}
</button>
</div>
{/* Sidebar Links */}
<motion.nav
className={cn(
direction === "horizontal" ? "flex-row" : "flex-col",
"flex"
)}
>
{links.map((link, index) => (
<a
key={index}
href={link.href}
className="flex items-center p-4 gap-4 "
>
<link.icon size={24} />
{open && <span>{link.label}</span>}
</a>
))}
</motion.nav>
</motion.div>
);
};
export default Sidebar;
Usage
Import the component:
import { Sidebar } from './components/ui';
Basic Usage
import { Home, Settings, User, Mail } from 'lucide-react';
function BasicSidebar() {
const links = [
{ label: 'Home', href: '/', icon: Home },
{ label: 'Profile', href: '/profile', icon: User },
{ label: 'Settings', href: '/settings', icon: Settings },
{ label: 'Contact', href: '/contact', icon: Mail },
];
return (
<Sidebar
links={links}
brandName="My App"
/>
);
}
Variants
- Preview
- Code
Demo Window
Demo App
<Sidebar
links={[
{ label: 'Home', href: '#', icon: Home },
{ label: 'Profile', href: '#', icon: User },
{ label: 'Settings', href: '#', icon: Settings },
{ label: 'Help', href: '#', icon: HelpCircle },
]}
brandName="Demo App"
variant="default"
position="left"
/>
Customization
With Custom Link Styling
function CustomStyledSidebar() {
const links = [
{ label: 'Home', href: '/', icon: Home },
{ label: 'Settings', href: '/settings', icon: Settings },
];
return (
<Sidebar
links={links}
brandName="Custom Links"
className="[&_a]:hover:bg-blue-500 [&_a]:transition-colors"
/>
);
}
Responsive Sidebar
Create a responsive sidebar that adapts to different screen sizes:
import { useState, useEffect } from 'react';
function ResponsiveSidebar() {
const [isOpen, setIsOpen] = useState(true);
useEffect(() => {
const handleResize = () => {
setIsOpen(window.innerWidth > 768);
};
window.addEventListener('resize', handleResize);
handleResize();
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<Sidebar
links={links}
isOpen={isOpen}
onClose={() => setIsOpen(false)}
className="md:relative absolute"
/>
);
}