'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 (
<>
>
)
}
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')
)}
))}
)}
)
}