site: implemenet docs navLink
This commit is contained in:
committed by
Johannes Kirschbauer
parent
6614138fb8
commit
b3dd1c4a46
@@ -1,13 +1,32 @@
|
|||||||
<script>
|
<script lang="ts">
|
||||||
let { data, children } = $props();
|
import type { NormalizedNavLink } from "./utils";
|
||||||
let { paths } = data;
|
let { children, data } = $props();
|
||||||
</script>
|
</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">
|
<div class="container">
|
||||||
<nav>
|
<nav>
|
||||||
{#each paths as path}
|
<ul>
|
||||||
<li><a href={`/docs/${path}`}>{path}</a></li>
|
{#each data.navLinks as navLink}
|
||||||
{/each}
|
{@render navLinkSnippet(navLink)}
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{@render children()}
|
{@render children()}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const articles = import.meta.glob("./**/*.md");
|
import { navLinks } from "./settings";
|
||||||
|
import { normalizeNavLinks } from "./utils";
|
||||||
|
|
||||||
export function load() {
|
export function load() {
|
||||||
const paths = Object.keys(articles).map(
|
return {
|
||||||
(key) => key.slice("./".length, -".md".length) + "/",
|
navLinks: normalizeNavLinks(navLinks),
|
||||||
);
|
};
|
||||||
return { paths };
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
import { error } from "@sveltejs/kit";
|
import { error } from "@sveltejs/kit";
|
||||||
|
|
||||||
const articles = import.meta.glob<{
|
const articles = Object.fromEntries(
|
||||||
content: string;
|
Object.entries(
|
||||||
frontmatter: {};
|
import.meta.glob<{
|
||||||
toc: {};
|
content: string;
|
||||||
}>("../**/*.md");
|
frontmatter: Record<string, any>;
|
||||||
|
toc: string;
|
||||||
|
}>("../**/*.md"),
|
||||||
|
).map(([key, fn]) => [key.slice("../".length, -".md".length), fn]),
|
||||||
|
);
|
||||||
|
|
||||||
export async function load({ params }) {
|
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) {
|
if (!article) {
|
||||||
error(404, "");
|
error(404, "");
|
||||||
}
|
}
|
||||||
|
|||||||
8
site/src/routes/docs/settings.ts
Normal file
8
site/src/routes/docs/settings.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import type { NavLink } from "./utils";
|
||||||
|
|
||||||
|
export const navLinks: NavLink[] = [
|
||||||
|
{
|
||||||
|
label: "Getting Started",
|
||||||
|
items: ["getting-started/add-machines"],
|
||||||
|
},
|
||||||
|
];
|
||||||
91
site/src/routes/docs/utils.ts
Normal file
91
site/src/routes/docs/utils.ts
Normal 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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user