import { Component, createSignal, onMount, Show } from "solid-js"; import { generateToc, type FileNode, type TocNode } from "../data-loader"; import { useLocation, useNavigate } from "@solidjs/router"; interface SidebarProps { isOpen: boolean; onClose: () => void; } /** * 文件树节点组件 */ const FileTreeNode: Component<{ node: FileNode; currentPath: string; pathHeadings: Record; depth: number; }> = (props) => { const navigate = useNavigate(); const [isExpanded, setIsExpanded] = createSignal(true); const isDir = !!props.node.children; const isActive = props.currentPath === props.node.path; const handleClick = () => { if (isDir) { setIsExpanded(!isExpanded()); } else { navigate(props.node.path); props.onClose(); } }; const indent = props.depth * 12; return (
{isExpanded() ? "📂" : "📁"} 📄 {props.node.name}
{props.node.children!.map((child) => ( ))}
); }; /** * 标题节点组件 */ const HeadingNode: Component<{ node: TocNode; basePath: string; depth: number; }> = (props) => { const navigate = useNavigate(); const anchor = props.node.title.toLowerCase().replace(/\s+/g, "-"); const href = `${props.basePath}#${anchor}`; const handleClick = (e: MouseEvent) => { e.preventDefault(); navigate(href); }; const indent = props.depth * 12; return (
{props.node.title}
{props.node.children!.map((child) => ( ))}
); }; /** * 侧边栏组件 */ export const Sidebar: Component = (props) => { const location = useLocation(); const [fileTree, setFileTree] = createSignal([]); const [pathHeadings, setPathHeadings] = createSignal< Record >({}); const [currentFileHeadings, setCurrentFileHeadings] = createSignal( [], ); onMount(async () => { const toc = await generateToc(); setFileTree(toc.fileTree); setPathHeadings(toc.pathHeadings); }); // 根据当前路径更新当前文件的标题列表 onMount(() => { const updateHeadings = () => { const pathname = location.pathname; const headings = pathHeadings()[pathname] || pathHeadings()[`${pathname}.md`]; setCurrentFileHeadings(headings || []); }; updateHeadings(); }); return ( {/* 遮罩层 */}
{/* 侧边栏 */} ); };