--- title: Ai Sidebar description: A feature-packed, professional AI navigation sidebar with brand header, live chat history categories, search filter, new chat shortcut, hover actions (pin, rename, delete), collapsed rail view, and user profile footer. Fully prop-driven. --- ## Installation CLI Manual ```bash npx lightswind@latest add ai-sidebar ``` Copy and paste the following code into your project. ```tsx "use client"; import React, { useState, useRef, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { SquarePen, Search, PanelLeft, PanelLeftClose, Images, Library, Puzzle, FolderKanban, Terminal, MoreHorizontal, Pin, Pencil, Trash2, Share2, Archive, Download, Sparkles, Settings, LogOut, Check, X, Bot, Command as CmdIcon, } from "lucide-react"; import { cn } from "@/components/lib/utils"; import { Button } from "@/components/lightswind/button"; import { Input } from "@/components/lightswind/input"; import { Avatar, AvatarImage, AvatarFallback } from "@/components/lightswind/avatar"; export interface SidebarNavItem { id: string; label: string; icon: React.ReactNode; badge?: string; onClick?: () => void; } export interface ChatHistoryItem { id: string; title: string; timestamp?: string; pinned?: boolean; archived?: boolean; } export interface ChatHistoryGroup { category: string; items: ChatHistoryItem[]; } export interface SidebarUser { name: string; email?: string; avatarUrl?: string; plan?: string; } export interface CustomChatItemAction { id: string; label: string; icon?: React.ReactNode; danger?: boolean; onClick?: (chat: ChatHistoryItem) => void; } export interface AiSidebarProps { brandName?: string; brandLogo?: React.ReactNode; navItems?: SidebarNavItem[]; moreNavItems?: SidebarNavItem[]; chatHistoryGroups?: ChatHistoryGroup[]; activeChatId?: string; user?: SidebarUser; collapsed?: boolean; searchQuery?: string; customChatActions?: CustomChatItemAction[]; onSearchChange?: (query: string) => void; onToggleCollapse?: () => void; onNewChat?: () => void; onSelectChat?: (chatId: string) => void; onDeleteChat?: (chatId: string) => void; onPinChat?: (chatId: string) => void; onRenameChat?: (chatId: string, newTitle: string) => void; onShareChat?: (chatId: string) => void; onArchiveChat?: (chatId: string) => void; onExportChat?: (chatId: string) => void; onUpgradeClick?: () => void; className?: string; } const DEFAULT_NAV_ITEMS: SidebarNavItem[] = [ { id: "images", label: "Images", icon: }, { id: "library", label: "Library", icon: }, { id: "plugins", label: "Plugins", icon: }, { id: "projects", label: "Projects", icon: }, { id: "codex", label: "Codex", icon: }, ]; const DEFAULT_MORE_NAV_ITEMS: SidebarNavItem[] = [ { id: "gpts", label: "Custom GPTs", icon: }, { id: "archived", label: "Archived Chats", icon: }, { id: "shortcuts", label: "Shortcuts", icon: }, ]; const DEFAULT_CHAT_GROUPS: ChatHistoryGroup[] = [ { category: "Recents", items: [ { id: "chat-1", title: "CSS Position Concept Reel", pinned: true }, { id: "chat-2", title: "Cross-posting Monetization Clarity" }, { id: "chat-3", title: "Induction Stove for Cooking" }, { id: "chat-4", title: "Flexbox Grid Learning Tool" }, { id: "chat-5", title: "Professional Video Creation" }, { id: "chat-6", title: "Lightswind AI Fluid Blob" }, { id: "chat-7", title: "Lightswind UI Carousel Help" }, { id: "chat-8", title: "Correct Product Hunt Process" }, { id: "chat-9", title: "Deadpool vs Wolverine OTT" }, { id: "chat-10", title: "Anxiety vs Imagination" }, { id: "chat-11", title: "Thyroid Tablet and Soy" }, { id: "chat-12", title: "Redish Background Design" }, { id: "chat-13", title: "YouTube Shorts Revenue Estimate" }, { id: "chat-14", title: "Cover Image Request" }, { id: "chat-15", title: "Shader Compilation Error Fix" }, { id: "chat-16", title: "Interactive 3D Shader" }, { id: "chat-17", title: "Hyper-realistic Headshot Description" }, { id: "chat-18", title: "Lightswind UI Installation Guide" }, ], }, ]; const DEFAULT_USER: SidebarUser = { name: "J Muhilvanan", email: "muhil@lightswind.ui", plan: "Free", }; export const AiSidebar: React.FC = ({ brandName = "ChatGPT", brandLogo = , navItems = DEFAULT_NAV_ITEMS, moreNavItems = DEFAULT_MORE_NAV_ITEMS, chatHistoryGroups = DEFAULT_CHAT_GROUPS, activeChatId = "chat-1", user = DEFAULT_USER, collapsed = false, searchQuery, customChatActions, onSearchChange, onToggleCollapse, onNewChat, onSelectChat, onDeleteChat, onPinChat, onRenameChat, onShareChat, onArchiveChat, onExportChat, onUpgradeClick, className, }) => { const [internalQuery, setInternalQuery] = useState(""); const [isSearching, setIsSearching] = useState(false); const [activeChat, setActiveChat] = useState(activeChatId); const [editingChatId, setEditingChatId] = useState(null); const [editingTitle, setEditingTitle] = useState(""); const [openMenuId, setOpenMenuId] = useState(null); const [showMoreNav, setShowMoreNav] = useState(false); const [showUserMenu, setShowUserMenu] = useState(false); const query = searchQuery !== undefined ? searchQuery : internalQuery; const setQuery = onSearchChange || setInternalQuery; const searchInputRef = useRef(null); useEffect(() => { if (isSearching) { searchInputRef.current?.focus(); } }, [isSearching]); const handleStartRename = (id: string, currentTitle: string) => { setEditingChatId(id); setEditingTitle(currentTitle); setOpenMenuId(null); }; const handleSaveRename = (id: string) => { if (editingTitle.trim() && onRenameChat) { onRenameChat(id, editingTitle.trim()); } setEditingChatId(null); }; const handleSelect = (id: string) => { setActiveChat(id); if (onSelectChat) onSelectChat(id); }; // Filter chats by search query const filteredGroups = chatHistoryGroups.map((group) => ({ ...group, items: group.items.filter((item) => item.title.toLowerCase().includes(query.toLowerCase()) ), })).filter((group) => group.items.length > 0); /* ── COLLAPSED SIDEBAR VIEW ── */ if (collapsed) { return ( ); } /* ── FULL EXPANDED SIDEBAR VIEW ── */ return ( ); }; export default AiSidebar; ``` ## Usage ```tsx import { AiSidebar } from "@/components/lightswind/ai-sidebar" ``` ```tsx import { AiSidebar } from "@/components/lightswind/ai-sidebar"; export function Demo() { return ( console.log("New chat")} onSelectChat={(id) => console.log("Selected:", id)} /> ); } ```