feat(sidebar): add collapsible toggle for libraries section

- Introduce `showLibraries` state to control libraries visibility
- Replace library header div with a toggle button
- Add rotate animation to the ChevronRight icon when expanded
- Conditionally render libraries list based on toggle state
- Maintain consistent styling for collapsed and expanded views
- Preserve link and button structure for each library item
This commit is contained in:
tigeren 2025-10-12 09:15:09 +00:00
parent 7d8694b6f5
commit a31973ea46
1 changed files with 45 additions and 33 deletions

View File

@ -29,6 +29,7 @@ const SidebarContent = () => {
const [libraries, setLibraries] = useState<{ id: number; path: string }[]>([]);
const [clusters, setClusters] = useState<Cluster[]>([]);
const [showClusters, setShowClusters] = useState(true);
const [showLibraries, setShowLibraries] = useState(true);
const pathname = usePathname();
const searchParams = useSearchParams();
@ -201,43 +202,54 @@ const SidebarContent = () => {
{/* Libraries Section */}
{libraries.length > 0 && (
<div className="pt-6 flex-1 flex flex-col overflow-hidden">
<div className={cn(
"flex items-center gap-2 px-3 mb-3 flex-shrink-0",
isCollapsed && "justify-center"
)}>
<button
onClick={() => setShowLibraries(!showLibraries)}
className={cn(
"flex items-center gap-2 px-3 mb-3 w-full hover:text-foreground transition-colors",
isCollapsed && "justify-center"
)}
>
<FolderOpen className="h-4 w-4 text-muted-foreground" />
{!isCollapsed && (
<h2 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
Libraries
</h2>
<>
<h2 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider flex-1 text-left">
Libraries
</h2>
<ChevronRight className={cn(
"h-3 w-3 text-muted-foreground transition-transform",
showLibraries && "rotate-90"
)} />
</>
)}
</div>
<div className="space-y-1 overflow-y-auto flex-1 sidebar-scrollbar">
{libraries.map((lib) => (
<Link
href={`/folder-viewer?path=${encodeURIComponent(lib.path)}`}
key={lib.id}
passHref
>
<Button
variant="ghost"
className={cn(
"w-full justify-start h-9 text-muted-foreground hover:text-foreground hover:bg-muted/50 rounded-lg transition-all group text-sm",
pathname === "/folder-viewer" &&
searchParams.get("path") === lib.path &&
"bg-accent text-accent-foreground border border-accent/20"
)}
</button>
{showLibraries && (
<div className="space-y-1 overflow-y-auto flex-1 sidebar-scrollbar">
{libraries.map((lib) => (
<Link
href={`/folder-viewer?path=${encodeURIComponent(lib.path)}`}
key={lib.id}
passHref
>
<Folder className="h-3.5 w-3.5 text-muted-foreground group-hover:text-foreground" />
{!isCollapsed && (
<span className="ml-3 truncate text-xs">
{lib.path.split('/').pop() || lib.path}
</span>
)}
</Button>
</Link>
))}
</div>
<Button
variant="ghost"
className={cn(
"w-full justify-start h-9 text-muted-foreground hover:text-foreground hover:bg-muted/50 rounded-lg transition-all group text-sm",
pathname === "/folder-viewer" &&
searchParams.get("path") === lib.path &&
"bg-accent text-accent-foreground border border-accent/20"
)}
>
<Folder className="h-3.5 w-3.5 text-muted-foreground group-hover:text-foreground" />
{!isCollapsed && (
<span className="ml-3 truncate text-xs">
{lib.path.split('/').pop() || lib.path}
</span>
)}
</Button>
</Link>
))}
</div>
)}
</div>
)}
</nav>