返回 CodeWhale
docs-sidebar.tsx
根目录 / web / components / docs-sidebar.tsx
1 "use client";
2
3 import Link from "next/link";
4 import { usePathname } from "next/navigation";
5 import { docsTopicIsCurrent } from "@/lib/docs-navigation";
6 import {
7 docTopicHref,
8 docTopicIsExternal,
9 getTopicsByCategory,
10 } from "@/lib/docs-map";
11
12 const CATEGORY_LABELS: Record<string, { en: string; zh: string }> = {
13 "getting-started": { en: "Getting started", zh: "入门" },
14 "core-concepts": { en: "Core concepts", zh: "核心概念" },
15 reference: { en: "Reference", zh: "参考" },
16 extending: { en: "Extending", zh: "扩展" },
17 operations: { en: "Operations", zh: "运维" },
18 };
19
20 export function DocsSidebar({ locale }: { locale: string }) {
21 const isZh = locale === "zh";
22 const pathname = usePathname();
23 const byCategory = getTopicsByCategory();
24
25 return (
26 <aside className="docs-sidebar min-w-0">
27 <div className="lg:sticky lg:top-24">
28 <div className="docs-sidebar-heading">
29 <Link href={`/${locale}/docs`}>
30 <span>{isZh ? "文档目录" : "Documentation"}</span>
31 <span aria-hidden="true">→</span>
32 </Link>
33 </div>
34 <nav aria-label={isZh ? "文档目录" : "Documentation index"}>
35 {[...byCategory.entries()].map(([category, topics]) => (
36 <div key={category} className="docs-sidebar-group">
37 <div className="docs-sidebar-category">
38 {isZh
39 ? CATEGORY_LABELS[category]?.zh ?? category
40 : CATEGORY_LABELS[category]?.en ?? category}
41 </div>
42 <ul>
43 {topics.map((topic) => {
44 const isCurrent = docsTopicIsCurrent(topic, locale, pathname);
45 const isExternal = docTopicIsExternal(topic);
46 return (
47 <li key={topic.id}>
48 <Link
49 href={docTopicHref(topic, locale)}
50 target={isExternal ? "_blank" : undefined}
51 rel={isExternal ? "noreferrer" : undefined}
52 aria-current={isCurrent ? "page" : undefined}
53 className={
54 isCurrent
55 ? "docs-sidebar-link docs-sidebar-link-current"
56 : "docs-sidebar-link"
57 }
58 >
59 <span>{isZh ? topic.label.zh : topic.label.en}</span>
60 {isExternal && <span aria-hidden="true">↗</span>}
61 </Link>
62 </li>
63 );
64 })}
65 </ul>
66 </div>
67 ))}
68 </nav>
69 </div>
70 </aside>
71 );
72 }
73
73 lines Plain Text