'use client' import { ArticleHeadings, SidebarContentArticleLink, SidebarContentCategoryLink, SidebarContentLink, SidebarContentList, SidebarContentSectionLink, } from '@/types/content-types' import * as Accordion from '@radix-ui/react-accordion' import Link from 'next/link' import { usePathname } from 'next/navigation' import { createContext, useContext, useEffect } from 'react' import { SectionLinks } from './Header' import { Chevron } from './Icons' import { Search } from './Search' import { SidebarCloseButton } from './SidebarCloseButton' import { ToggleMenuButton } from './ToggleMenuButton' type SidebarProps = SidebarContentList const linkContext = createContext<{ activeId: string | null articleId: string | null categoryId: string | null sectionId: string | null } | null>(null) export function Sidebar({ headings, links, sectionId, categoryId, articleId, searchQuery, searchType, }: SidebarProps) { const activeId = articleId ?? categoryId ?? sectionId const pathName = usePathname() useEffect(() => { document.body.classList.remove('sidebar-open') document.querySelector('.sidebar [data-active=true]')?.scrollIntoView({ block: 'center' }) // XXX(mime): scrolling the sidebar into position also scrolls the page to the wrong // spot. this compensates for that but, ugh. document.documentElement.scrollTop = 0 }, [pathName]) return ( <>
e.stopPropagation()}>
) } export function SidebarLinks({ headings, links, }: { headings?: ArticleHeadings links: SidebarContentLink[] }) { return ( ) } function SidebarLink({ headings, ...props }: SidebarContentLink & { headings?: ArticleHeadings }) { switch (props.type) { case 'section': { return } case 'article': { return } case 'category': { return } } } function SidebarSection({ title, children, headings, }: SidebarContentSectionLink & { headings?: ArticleHeadings }) { if (children.length === 0) return null return (
  • {title && {title}}
      {children.map((link) => ( ))}
  • ) } function SidebarCategory({ title, children }: SidebarContentCategoryLink) { const linkCtx = useContext(linkContext) if (children.length === 0) return null const hasGroups = children.some((child) => !!(child as SidebarContentArticleLink).groupId) const activeArticle = children.find( (child) => (child as SidebarContentArticleLink).articleId === linkCtx?.articleId ) const activeGroup = activeArticle && (activeArticle as SidebarContentArticleLink).groupId const groups = ['Class', 'Function', 'Variable', 'Interface', 'Enum', 'TypeAlias', 'Namespace'] return (
  • {hasGroups ? ( <> {title} {groups.map((group) => { const articles = children.filter( (child) => (child as SidebarContentArticleLink).groupId === group ) if (articles.length === 0) return null return ( {group}
      {articles.map((link) => ( ))}
    ) })}
    ) : ( <> {title}
      {children.map((link) => ( ))}
    )}
  • ) } function SidebarArticle({ title, url, articleId, headings, }: SidebarContentArticleLink & { headings?: ArticleHeadings }) { const isActive = useContext(linkContext)?.activeId === articleId return (
  • {title} {isActive && (
      {headings ?.filter((heading) => heading.level < 3) .map((heading) => (
    • {heading.isCode ? ( {heading.title.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')} ) : ( heading.title.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') )}
    • ))}
    )}
  • ) }