'use client' import { type ReactNode, useState } from 'react' import type { Folder, Item, Separator } from 'fumadocs-core/page-tree' import Link from 'next/link' import { usePathname } from 'next/navigation' import { i18n } from '@/lib/i18n' import { cn } from '@/lib/utils' function SidebarChevron({ open, className }: { open: boolean; className?: string }) { return ( ) } const LANG_PREFIXES = i18n.languages.map((l) => `/${l}`) function stripLangPrefix(path: string): string { for (const prefix of LANG_PREFIXES) { if (path === prefix) return '/' if (path.startsWith(`${prefix}/`)) return path.slice(prefix.length) } return path } function isActive(url: string, pathname: string, nested = true): boolean { const normalizedPathname = stripLangPrefix(pathname) const normalizedUrl = stripLangPrefix(url) return ( normalizedUrl === normalizedPathname || (nested && normalizedPathname.startsWith(`${normalizedUrl}/`)) ) } const ITEM_BASE = 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-[var(--text-muted)] text-sm transition-colors hover:bg-[var(--surface-active)] hover:text-[var(--text-body)]' const ITEM_ACTIVE_MOBILE = 'bg-[var(--surface-active)] font-medium text-[var(--text-primary)]' const ITEM_DESKTOP = 'lg:mb-[0.0625rem] lg:block lg:rounded-lg lg:px-2.5 lg:py-1.5 lg:font-normal lg:text-[13px] lg:leading-tight' const ITEM_TEXT = 'lg:text-[var(--text-body)]' const ITEM_HOVER = 'lg:hover:bg-[var(--surface-3)]' const ITEM_ACTIVE = 'lg:bg-[var(--surface-active)] lg:font-normal lg:text-[var(--text-body)]' const FOLDER_TEXT = 'lg:text-[var(--text-body)] lg:font-medium' const FOLDER_HOVER = 'lg:hover:bg-[var(--surface-3)]' const FOLDER_ACTIVE = 'lg:bg-[var(--surface-active)] lg:text-[var(--text-body)]' export function SidebarItem({ item }: { item: Item }) { const pathname = usePathname() const active = isActive(item.url, pathname, false) return ( {item.name} ) } function isApiReferenceFolder(node: Folder): boolean { if (node.index?.url.includes('/api-reference/')) return true for (const child of node.children) { if (child.type === 'page' && child.url.includes('/api-reference/')) return true if (child.type === 'folder' && isApiReferenceFolder(child)) return true } return false } export function SidebarFolder({ item, children }: { item: Folder; children: ReactNode }) { const pathname = usePathname() const hasActiveChild = checkHasActiveChild(item, pathname) const isApiRef = isApiReferenceFolder(item) const isOnApiRefPage = stripLangPrefix(pathname).startsWith('/api-reference') const hasChildren = item.children.length > 0 const defaultOpen = hasActiveChild || (isApiRef && isOnApiRefPage) const [manualOpen, setManualOpen] = useState<{ pathname: string; open: boolean } | null>(null) const open = manualOpen?.pathname === pathname ? manualOpen.open : defaultOpen const toggleOpen = () => setManualOpen({ pathname, open: !open }) const active = item.index ? isActive(item.index.url, pathname, false) : false if (item.index && !hasChildren) { return ( {item.name} ) } return (
{item.index ? ( <> {item.name} {hasChildren && ( )} ) : ( )}
{hasChildren && (
{children}
    {children}
)}
) } export function SidebarSeparator({ item }: { item: Separator }) { return (

{item.name}

) } function checkHasActiveChild(node: Folder, pathname: string): boolean { if (node.index && isActive(node.index.url, pathname)) { return true } for (const child of node.children) { if (child.type === 'page' && isActive(child.url, pathname)) { return true } if (child.type === 'folder' && checkHasActiveChild(child, pathname)) { return true } } return false }