Files
v10/site/src/components/docs/SidebarItem.astro
T
2026-02-24 15:34:34 -06:00

106 lines
3.2 KiB
Plaintext

---
import GithubSlugger from 'github-slugger';
import { ChevronDown } from 'lucide-react';
import type { Guide, Section, SupportedFramework } from '@/types/docs';
import { isSection } from '@/types/docs';
type Props = {
item: Guide | Section;
framework: SupportedFramework;
docTitles: Map<string, string>;
depth?: number;
};
const { item, framework, docTitles, depth = 0 } = Astro.props;
const currentPath = Astro.url.pathname;
const slugger = new GithubSlugger();
// Helper to check if this item or any of its children contains the active path
function containsActivePath(item: Guide | Section): boolean {
if (isSection(item)) {
return item.contents.some((child) => containsActivePath(child));
} else {
const itemPath = `/docs/framework/${framework}/${item.slug}`;
return itemPath === currentPath;
}
}
const isActive = containsActivePath(item);
function getGroup(depth: number) {
if (depth === 0) return 'group';
if (depth === 1) return 'group/1';
if (depth === 2) return 'group/2';
return '';
}
function getGroupMargin(depth: number) {
if (depth === 1) return 'group-open/1:mb-1';
if (depth === 2) return 'group-open/2:mb-1';
return '';
}
function getGroupRotate(depth: number) {
if (depth === 0) return 'group-open:rotate-180';
if (depth === 1) return 'group-open/1:rotate-180';
if (depth === 2) return 'group-open/2:rotate-180';
return '';
}
---
{
isSection(item) ? (
<details
id={slugger.slug(item.sidebarLabel)}
open={isActive || item.defaultOpen !== false}
class:list={[
getGroup(depth),
depth === 0 && 'my-4 first:mt-0',
]}
>
<summary
class:list={[
'py-2 flex items-center gap-4 ',
'intent:text-dark-100 dark:intent:text-light-80 cursor-pointer',
(depth === 0 || depth === 1) && 'font-medium',
depth > 0 && 'border-l pl-4',
isActive ? 'text-dark-100 dark:text-light-100 border-dark-100' : 'border-light-40 dark:border-dark-40',
getGroupMargin(depth)
]}
style={depth ? `margin-left: calc(var(--spacing) * ${(depth - 1) * 4})` : ``}
>
<span class="flex-1">{item.sidebarLabel}</span>
<ChevronDown size={12} className={getGroupRotate(depth)} />
</summary>
<div>
{item.contents.map((contentItem) => (
<Astro.self item={contentItem} framework={framework} docTitles={docTitles} depth={depth + 1} />
))}
</div>
</details>
) : (
<a
aria-current={isActive ? 'page' : undefined}
class:list={[
'py-2 flex items-center gap-4 ',
'intent:text-dark-100 dark:intent:text-light-100 cursor-pointer',
depth === 0 && 'font-medium',
depth > 0 && 'border-l pl-4',
isActive ? 'text-dark-100 dark:text-light-100 border-current ' : 'border-light-40 dark:border-dark-40',
]}
style={`margin-left: calc(var(--spacing) * ${(depth - 1) * 4})`}
href={`/docs/framework/${framework}/${item.slug}`}
>
{item.devOnly ? '[Dev only] ' : ''}
{item.sidebarLabel || docTitles.get(item.slug) || item.slug}
</a>
)
}
<style>
summary {
list-style: none;
}
summary::-webkit-details-marker {
display: none;
}
</style>