import { Component, createMemo, createSignal, onMount, Show } from "solid-js"; import { generateToc, type FileNode, type TocNode } from "../data-loader"; import { useLocation } from "@solidjs/router"; import { FileTreeNode, HeadingNode } from "./FileTree"; export interface SidebarProps { isOpen: boolean; onClose: () => void; fileTree?: FileNode[]; pathHeadings?: Record; onDataSourceOpen?: () => void; } interface SidebarContentProps { fileTree: FileNode[]; pathHeadings: Record; currentPath: string; onClose: () => void; isDesktop?: boolean; onDataSourceOpen?: () => void; } /** * 侧边栏内容组件 */ const SidebarContent: Component = (props) => { const location = useLocation(); // 响应式获取当前文件的标题列表 const currentFileHeadings = createMemo(() => { const pathname = decodeURIComponent(location.pathname); return ( props.pathHeadings[pathname] || props.pathHeadings[`${pathname}.md`] || [] ); }); return (

目录

{/* 文件树滚动区域 */}

文件

{props.fileTree.map((node) => ( ))}
{/* 当前文件标题滚动区域 */} 0}>

本页

{currentFileHeadings().map((node) => ( ))}
); }; /** * 侧边栏组件(移动端抽屉) */ export const MobileSidebar: Component = (props) => { const location = useLocation(); const [selfFileTree, setSelfFileTree] = createSignal([]); const [selfPathHeadings, setSelfPathHeadings] = createSignal< Record >({}); const fileTree = () => props.fileTree ?? selfFileTree(); const pathHeadings = () => props.pathHeadings ?? selfPathHeadings(); // 加载目录数据 (only if props not provided) onMount(async () => { if (props.fileTree && props.pathHeadings) return; const toc = await generateToc(); setSelfFileTree(toc.fileTree); setSelfPathHeadings(toc.pathHeadings); }); return ( <> {/* 遮罩层 */}
{/* 侧边栏 */} ); }; /** * 桌面端固定侧边栏 */ export const DesktopSidebar: Component<{ fileTree?: FileNode[]; pathHeadings?: Record; onDataSourceOpen?: () => void; }> = (props) => { const location = useLocation(); const [selfFileTree, setSelfFileTree] = createSignal([]); const [selfPathHeadings, setSelfPathHeadings] = createSignal< Record >({}); const fileTree = () => props.fileTree ?? selfFileTree(); const pathHeadings = () => props.pathHeadings ?? selfPathHeadings(); onMount(async () => { if (props.fileTree && props.pathHeadings) return; const toc = await generateToc(); setSelfFileTree(toc.fileTree); setSelfPathHeadings(toc.pathHeadings); }); return ( ); };