11"use client"
22
33import { useDeferredValue , useMemo , useRef , useState } from "react"
4- import { ChevronRight } from "lucide-react"
4+ import { ChevronDown , ChevronRight } from "lucide-react"
55
66import { Button } from "@/components/ui/buttons/Button"
7+ import {
8+ Collapsible ,
9+ CollapsibleContent ,
10+ CollapsibleTrigger ,
11+ } from "@/components/ui/collapsible"
712import Input from "@/components/ui/input"
813import { BaseLink } from "@/components/ui/Link"
914import { Section } from "@/components/ui/section"
@@ -89,6 +94,7 @@ type CategorySidebarProps = {
8994 currentCategoryId ?: string
9095 selectedSubcategoryId ?: string
9196 onSelectSubcategory : ( subcategoryId ?: string ) => void
97+ showAllLink ?: boolean
9298}
9399
94100function CategorySidebar ( {
@@ -103,22 +109,25 @@ function CategorySidebar({
103109 currentCategoryId,
104110 selectedSubcategoryId,
105111 onSelectSubcategory,
112+ showAllLink = true ,
106113} : CategorySidebarProps ) {
107114 const nf = numberFormat ( locale )
108115 return (
109116 < div className = "space-y-1" >
110- < BaseLink
111- href = "/developers/tools/"
112- className = { cn (
113- "flex w-full items-center justify-between rounded-md px-3 py-2 text-start text-sm no-underline hover:bg-background-highlight" ,
114- ! currentCategoryId && "bg-background-highlight text-primary"
115- ) }
116- >
117- < span > { allCategoriesLabel } </ span >
118- < span className = "text-xs text-body-medium" >
119- { nf . format ( totalCount ) }
120- </ span >
121- </ BaseLink >
117+ { showAllLink && (
118+ < BaseLink
119+ href = "/developers/tools/"
120+ className = { cn (
121+ "flex w-full items-center justify-between rounded-md px-3 py-2 text-start text-sm no-underline hover:bg-background-highlight" ,
122+ ! currentCategoryId && "bg-background-highlight text-primary"
123+ ) }
124+ >
125+ < span > { allCategoriesLabel } </ span >
126+ < span className = "text-xs text-body-medium" >
127+ { nf . format ( totalCount ) }
128+ </ span >
129+ </ BaseLink >
130+ ) }
122131
123132 { categories . map ( ( category ) => {
124133 const isCurrent = currentCategoryId === category . id
@@ -313,21 +322,19 @@ export default function ToolsCatalog({
313322 . filter ( ( group ) => group . count > 0 )
314323 } , [ categories , filteredTools ] )
315324
316- const sidebar = (
317- < CategorySidebar
318- locale = { locale }
319- categories = { categories }
320- categoryLabels = { categoryLabels }
321- subcategoryLabels = { subcategoryLabels }
322- countByCategory = { countByCategory }
323- countBySubcategory = { countBySubcategory }
324- totalCount = { totalCount }
325- allCategoriesLabel = { labels . allCategories }
326- currentCategoryId = { currentCategoryId }
327- selectedSubcategoryId = { selectedSubcategoryId }
328- onSelectSubcategory = { handleSelectSubcategory }
329- />
330- )
325+ const sidebarProps : CategorySidebarProps = {
326+ locale,
327+ categories,
328+ categoryLabels,
329+ subcategoryLabels,
330+ countByCategory,
331+ countBySubcategory,
332+ totalCount,
333+ allCategoriesLabel : labels . allCategories ,
334+ currentCategoryId,
335+ selectedSubcategoryId,
336+ onSelectSubcategory : handleSelectSubcategory ,
337+ }
331338
332339 return (
333340 < Section id = "catalog" className = "space-y-5" >
@@ -341,7 +348,7 @@ export default function ToolsCatalog({
341348 className = "w-full"
342349 />
343350 < div className = "max-h-[calc(100vh-11rem)] overflow-y-auto rounded-xl border p-2" >
344- { sidebar }
351+ < CategorySidebar { ... sidebarProps } />
345352 </ div >
346353 </ div >
347354 </ aside >
@@ -354,7 +361,29 @@ export default function ToolsCatalog({
354361 placeholder = { labels . searchPlaceholder }
355362 className = "w-full"
356363 />
357- < div className = "rounded-xl border p-2" > { sidebar } </ div >
364+ < Collapsible className = "rounded-xl border" >
365+ < CollapsibleTrigger className = "group flex w-full items-center justify-between gap-2 rounded-xl px-4 py-3 text-sm hover:bg-background-highlight focus-visible:outline-1 focus-visible:-outline-offset-1 focus-visible:outline-primary-hover" >
366+ < span className = "flex-1 text-start" >
367+ { currentCategoryId
368+ ? getCategoryLabel ( currentCategoryId , categoryLabels )
369+ : labels . allCategories }
370+ </ span >
371+ < span className = "text-xs text-body-medium" >
372+ { nf . format (
373+ currentCategoryId
374+ ? countByCategory [ currentCategoryId ] || 0
375+ : totalCount
376+ ) }
377+ </ span >
378+ < ChevronDown className = "size-4 shrink-0 text-body-medium transition-transform group-data-[state=open]:rotate-180" />
379+ </ CollapsibleTrigger >
380+ < CollapsibleContent className = "p-2 pt-0" >
381+ < CategorySidebar
382+ { ...sidebarProps }
383+ showAllLink = { ! ! currentCategoryId }
384+ />
385+ </ CollapsibleContent >
386+ </ Collapsible >
358387 </ div >
359388 < div ref = { resultsTopRef } className = "scroll-mt-24" />
360389 { ( currentCategoryId || selectedSubcategoryId ) && (
0 commit comments