Skip to content

Commit

Permalink
feat: table of content for blog post
Browse files Browse the repository at this point in the history
  • Loading branch information
yjose committed Dec 31, 2024
1 parent a72cf26 commit 98251e2
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 13 deletions.
26 changes: 13 additions & 13 deletions src/components/blog/article-details.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ShareArticle from "./share-article.astro";
import BlogImage from "./blog-image.astro";
import ArticleNavigation from "./article-navigation.astro";
import PageViews from "./page-views.astro";
import TableOfContents from "./table-of-contents.astro";

export interface Props {
article: CollectionEntry<"blog">;
Expand All @@ -20,7 +21,7 @@ const { title, description, ogImage } = article.data;
const pageUrl = new URL(Astro.url.pathname, Astro.url.origin).href;

const minutesRead = getReadingTime(article.body ?? "").text;
const { Content } = await render(article);
const { Content, headings } = await render(article);
const authors = article.data.authors
? await getEntries(article.data.authors)
: undefined;
Expand All @@ -39,10 +40,6 @@ const authors = article.data.authors
<div
class="relative my-3 flex flex-row items-center text-sm italic text-gray-600 md:text-base"
>
<!-- <div class="my-3 flex flex-row flex-wrap items-end">
<Datetime datetime={pubDatetime} size="lg" className="mr-2" />
</div> -->

<div class="flex items-center text-base">
{
authors?.map(author => (
Expand Down Expand Up @@ -79,17 +76,20 @@ const authors = article.data.authors
}
</div>

<article
id="article"
role="article"
class="prose mx-auto mt-8 max-w-3xl prose-pre:border-[1px] prose-pre:border-solid prose-pre:border-gray-300"
>
<Content />
</article>
<div class="relative mx-auto max-w-3xl">
<article
id="article"
role="article"
class="prose mx-auto mt-8 max-w-none prose-pre:border-[1px] prose-pre:border-solid prose-pre:border-gray-300"
>
<Content />
</article>
<TableOfContents headings={headings} />
</div>
<ShareArticle />
<ArticleNavigation article={article} />

<div class="mx-auto mt-10 w-full max-w-3xl">
<div class="mx-auto mt-10 max-w-3xl">
<ArticleComments />
</div>
</main>
Expand Down
41 changes: 41 additions & 0 deletions src/components/blog/table-of-contents.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
interface Props {
headings: {
depth: number;
slug: string;
text: string;
}[];
}

const { headings } = Astro.props;
const h2Headings = headings.filter(heading => heading.depth === 2);
---

<aside class="absolute left-full top-0 ml-8 hidden h-full lg:block">
<nav class="sticky top-12 w-64" aria-label="Table of contents">
<div class="rounded-lg bg-white/50 p-4 shadow-sm">
<h2 class="mb-4 text-sm font-semibold text-gray-900">On this page</h2>
<ul class="space-y-2 text-sm">
{
h2Headings.map(heading => (
<li class="hover:text-primary font-sans text-sm font-medium">
<a
href={`#${heading.slug}`}
class="hover:text-primary block text-gray-500"
>
{heading.text}
</a>
</li>
))
}
</ul>
</div>
</nav>
</aside>

<style>
nav {
max-height: calc(100vh - 8rem);
overflow-y: auto;
}
</style>

0 comments on commit 98251e2

Please sign in to comment.