site: implemenet docs navLink

This commit is contained in:
Glen Huang
2025-10-07 21:27:33 +08:00
committed by Johannes Kirschbauer
parent 6614138fb8
commit b3dd1c4a46
5 changed files with 142 additions and 17 deletions

View File

@@ -1,13 +1,32 @@
<script>
let { data, children } = $props();
let { paths } = data;
<script lang="ts">
import type { NormalizedNavLink } from "./utils";
let { children, data } = $props();
</script>
{#snippet navLinkSnippet(navLink: NormalizedNavLink)}
{#if "items" in navLink}
<li>
<span class="label group">{navLink.label}</span>
<ul>
{#each navLink.items as item}
{@render navLinkSnippet(item)}
{/each}
</ul>
</li>
{:else}
<li>
<a href={navLink.slug}>{navLink.label}</a>
</li>
{/if}
{/snippet}
<div class="container">
<nav>
{#each paths as path}
<li><a href={`/docs/${path}`}>{path}</a></li>
{/each}
<ul>
{#each data.navLinks as navLink}
{@render navLinkSnippet(navLink)}
{/each}
</ul>
</nav>
<div class="content">
{@render children()}

View File

@@ -1,8 +1,8 @@
const articles = import.meta.glob("./**/*.md");
import { navLinks } from "./settings";
import { normalizeNavLinks } from "./utils";
export function load() {
const paths = Object.keys(articles).map(
(key) => key.slice("./".length, -".md".length) + "/",
);
return { paths };
return {
navLinks: normalizeNavLinks(navLinks),
};
}

View File

@@ -1,13 +1,20 @@
import { error } from "@sveltejs/kit";
const articles = import.meta.glob<{
content: string;
frontmatter: {};
toc: {};
}>("../**/*.md");
const articles = Object.fromEntries(
Object.entries(
import.meta.glob<{
content: string;
frontmatter: Record<string, any>;
toc: string;
}>("../**/*.md"),
).map(([key, fn]) => [key.slice("../".length, -".md".length), fn]),
);
export async function load({ params }) {
const article = articles[`../${params.path.slice(0, -"/".length)}.md`];
const path = params.path.endsWith("/")
? params.path.slice(0, -1)
: params.path;
const article = articles[path];
if (!article) {
error(404, "");
}

View File

@@ -0,0 +1,8 @@
import type { NavLink } from "./utils";
export const navLinks: NavLink[] = [
{
label: "Getting Started",
items: ["getting-started/add-machines"],
},
];

View File

@@ -0,0 +1,91 @@
export const articles = Object.fromEntries(
Object.entries(
import.meta.glob<{
content: string;
frontmatter: Record<string, any>;
toc: string;
}>("./**/*.md", { eager: true }),
).map(([key, fn]) => [key.slice("./".length, -".md".length), fn]),
);
export type NavLink =
| string
| {
label: string;
items: NavLink[];
badge?: Badge;
}
| {
label?: string;
slug: string;
badge?: Badge;
};
export type NormalizedNavLink =
| {
label: string;
items: NormalizedNavLink[];
badge?: NormalizedBadge;
}
| {
label: string;
slug: string;
badge?: NormalizedBadge;
};
export type Badge = string | NormalizedBadge;
export type NormalizedBadge = {
text: string;
variant: "caution" | "normal";
};
export function normalizeNavLinks(navLinks: NavLink[]): NormalizedNavLink[] {
return navLinks.map(normalizeNavLink);
}
export function normalizeNavLink(navLink: NavLink): NormalizedNavLink {
if (typeof navLink === "string") {
const article = articles[navLink];
if (!article) {
throw new Error(`Doc not found: ${navLink}`);
}
return {
label: article.frontmatter.title,
slug: `/docs/${navLink}`,
};
}
if (!("items" in navLink)) {
const article = articles[navLink.slug];
if (!article) {
throw new Error(`Doc not found: ${navLink}`);
}
return {
...navLink,
label: navLink.label ?? article.frontmatter.title,
badge: normalizeBadge(navLink.badge),
};
}
return {
...navLink,
badge: normalizeBadge(navLink.badge),
items: navLink.items.map(normalizeNavLink),
};
}
export function normalizeBadge(
badge: Badge | undefined,
): NormalizedBadge | undefined {
if (!badge) {
return undefined;
}
if (typeof badge === "string") {
return {
text: badge,
variant: "normal",
};
}
return badge;
}