From eee2f60c611d623c7abf94badc3ca6fede002636 Mon Sep 17 00:00:00 2001 From: Araozu Date: Mon, 26 Aug 2024 11:05:21 -0500 Subject: [PATCH] feat: Implement sidebar for api docs --- public/css/global.css | 2 +- src/components/ApiLayout/Sidebar.astro | 43 ++++++++++++++ src/layouts/ApiLayout.astro | 78 +++++++++++++++++++++++++- src/layouts/PagesLayout.astro | 24 ++------ src/layouts/utils.ts | 17 ++++++ tailwind.config.mjs | 2 +- 6 files changed, 145 insertions(+), 21 deletions(-) create mode 100644 src/components/ApiLayout/Sidebar.astro create mode 100644 src/layouts/utils.ts diff --git a/public/css/global.css b/public/css/global.css index fec7533..30c5620 100644 --- a/public/css/global.css +++ b/public/css/global.css @@ -51,7 +51,7 @@ --c-primary: rgb(255, 180, 180); --c-pink: #374259; --c-link: #0284c7; - --c-border-1: #9090r0; + --c-border-1: #909090; --c-nav-bg: rgb(255, 247, 255, 0.5); --c-secondary: rgba(255, 255, 240, 0.5); diff --git a/src/components/ApiLayout/Sidebar.astro b/src/components/ApiLayout/Sidebar.astro new file mode 100644 index 0000000..02adf14 --- /dev/null +++ b/src/components/ApiLayout/Sidebar.astro @@ -0,0 +1,43 @@ +--- +import type { Hierarchy, Post } from "../../layouts/ApiLayout.astro"; + +const hierarchy: Hierarchy = Astro.props.hierarchy; + +function splitAndLast(s: string): string { + const segments = s.split("/"); + return segments[segments.length - 1]!; +} + +function postComparison(a: Post, b: Post): number { + const s1 = splitAndLast(a.url); + const s2 = splitAndLast(b.url); + + return s1 > s2 ? 0 : 1; +} +--- + +{ + Object.entries(hierarchy.children).map(([folderName, children]) => ( + <> +
+ {folderName} +
+ +
+ +
+ + )) +} +{ + hierarchy.posts.sort(postComparison).map((p) => ( + + {splitAndLast(p.url)} + + )) +} diff --git a/src/layouts/ApiLayout.astro b/src/layouts/ApiLayout.astro index 74ca91d..f165128 100644 --- a/src/layouts/ApiLayout.astro +++ b/src/layouts/ApiLayout.astro @@ -2,8 +2,78 @@ import Navbar from "../components/Navbar.astro"; import BaseLayout from "./BaseLayout.astro"; import TOC from "../components/TOC.astro"; +import Sidebar from "../components/ApiLayout/Sidebar.astro"; const { headings } = Astro.props; + +export type Post = { + frontmatter: any; + getHeadings: any; + url: string; + file: any; + Content: any; + default: any; +}; +type Posts = Array>; + +const basePath = "/api/std"; +const posts: Posts = await Astro.glob("../pages/api/std/**/*.{md,mdx}"); + +export type Hierarchy = { + posts: Array; + children: Record; +}; + +function createHierarchy(posts: Posts): Hierarchy { + const hierarchy: Hierarchy = { + posts: [], + children: {}, + }; + + for (const post of posts) { + const postUrl: string = post.url; + const urlAfterBase = postUrl.split(basePath)[1] ?? ""; + + // handle / (index) + if (urlAfterBase === "") { + hierarchy.posts.push(post); + continue; + } + + const urlSegments = urlAfterBase.split("/").slice(1); + + // top level urls + if (urlSegments.length === 1) { + hierarchy.posts.push(post); + continue; + } + + // folders + const folders = urlSegments.slice(0, -1); + + // traverse the hierarchy until the neccesary hierarchy is found + let currentHierarchy = hierarchy; + for (const folderName of folders) { + // check if folder exists, create otherwise + if (!hierarchy.children[folderName]) { + // create if doesnt exist + hierarchy.children[folderName] = { + posts: [], + children: {}, + }; + } + + currentHierarchy = hierarchy.children[folderName]; + } + + // add the page + currentHierarchy.posts.push(post); + } + + return hierarchy; +} + +const hierarchy = createHierarchy(posts); --- @@ -16,7 +86,7 @@ const { headings } = Astro.props; border-c-border-1 -translate-x-64 lg:translate-x-0 transition-transform" > @@ -39,4 +109,10 @@ const { headings } = Astro.props; + + diff --git a/src/layouts/PagesLayout.astro b/src/layouts/PagesLayout.astro index 6a7cdf9..c7cc238 100644 --- a/src/layouts/PagesLayout.astro +++ b/src/layouts/PagesLayout.astro @@ -77,7 +77,9 @@ for (const entry of pagesIndex) { -
+
diff --git a/src/layouts/utils.ts b/src/layouts/utils.ts new file mode 100644 index 0000000..422848a --- /dev/null +++ b/src/layouts/utils.ts @@ -0,0 +1,17 @@ + +export function sidebarHighlight() { + let current_uri = window.location.pathname; + + const sidebar = document.getElementById("sidebar")! + .children[0]! as HTMLElement; + const links = sidebar.querySelectorAll("a"); + for (const link of [...links]) { + if (link.getAttribute("href") === current_uri) { + sidebar.scrollTop = + link.offsetTop - sidebar.offsetTop - 250; + + link.classList.add("bg-pink-200", "dark:bg-pink-950"); + break; + } + } +} diff --git a/tailwind.config.mjs b/tailwind.config.mjs index f42d97a..6333394 100644 --- a/tailwind.config.mjs +++ b/tailwind.config.mjs @@ -9,7 +9,7 @@ export default { "c-text": "var(--c-text)", "c-text-2": "var(--c-text-2)", "c-purple": "var(--c-purple)", - "c-border-1": "rgba(150,150,150,0.25)", + "c-border-1": "var(--c-border-1)", "c-purple-light": "var(--c-purple-light)", "c-box-shadow": "var(--c-box-shadow)", "c-ping": "var(--c-pink)",