feat: enhancer toc

This commit is contained in:
KazooTTT
2025-02-07 17:19:02 +08:00
parent 2619f3c307
commit 84730146a6
6 changed files with 47 additions and 17 deletions

View File

@ -2,17 +2,25 @@
import { generateToc } from "@/utils/generateToc"; import { generateToc } from "@/utils/generateToc";
import type { MarkdownHeading } from "astro"; import type { MarkdownHeading } from "astro";
import TOCHeading from "./TOCHeading.astro"; import TOCHeading from "./TOCHeading.astro";
import { cn } from "@/utils/tailwind";
interface Props { interface Props {
headings: MarkdownHeading[]; headings: MarkdownHeading[];
classname?: string;
} }
const { headings } = Astro.props; const { headings, classname } = Astro.props;
const toc = generateToc(headings); const toc = generateToc(headings);
--- ---
<details open class="lg:sticky lg:top-12 lg:order-2 lg:-me-32 lg:basis-64"> <details
open
class={cn(
"[&::-webkit-scrollbar-thumb]:bg-accent/20 hover:[&::-webkit-scrollbar-thumb]:bg-accent/30 h-[calc(100vh-20rem)] overflow-x-hidden pr-4 lg:sticky lg:top-12 lg:order-2 lg:-me-32 lg:basis-64 [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-transparent",
classname
)}
>
<summary class="title hover:marker:text-accent cursor-pointer text-lg">Table of Contents</summary> <summary class="title hover:marker:text-accent cursor-pointer text-lg">Table of Contents</summary>
<nav class="ms-4 lg:w-full"> <nav class="ms-4 lg:w-full">
<ol class="mt-4"> <ol class="mt-4">

View File

@ -1,26 +1,26 @@
--- ---
import type { MarkdownHeading } from 'astro' import type { MarkdownHeading } from "astro";
import { generateToc } from '@/utils' import { generateToc } from "@/utils";
import TOCHeading from './TOCHeading.astro' import TOCHeading from "./TOCHeading.astro";
interface Props { interface Props {
headings: MarkdownHeading[] headings: MarkdownHeading[];
} }
const { headings } = Astro.props const { headings } = Astro.props;
const toc = generateToc(headings) const toc = generateToc(headings);
--- ---
<aside <aside
class='sticky top-20 order-2 -me-28 hidden h-[calc(100vh-6rem)] basis-60 lg:flex lg:flex-col' class="sticky top-20 order-2 -me-28 hidden h-[calc(100vh-6rem)] basis-60 lg:flex lg:flex-col"
> >
{ {
toc.length > 0 && ( toc.length > 0 && (
<> <>
<h2 class='mb-4 font-semibold'>TABLE OF CONTENTS</h2> <h2 class="mb-4 font-semibold">TABLE OF CONTENTS</h2>
<ul class='max-h-[calc(100vh-10rem)] overflow-y-auto pr-4 text-card-foreground'> <ul class="text-card-foreground max-h-[calc(100vh-10rem)] overflow-y-auto pr-4">
{toc.map((heading) => ( {toc.map((heading) => (
<TOCHeading heading={heading} /> <TOCHeading heading={heading} />
))} ))}

View File

@ -65,7 +65,7 @@ if (modifiedDate && modifiedDate.toDateString() === date.toDateString()) {
} }
</div> </div>
<div class="group w-full overflow-auto"> <div class="group w-full overflow-auto">
<div class="prose prose-sm prose-cactus mt-4 max-w-none [&>p:last-of-type]:mb-0"> <div class="prose prose-base prose-cactus mt-4 max-w-none [&>p:last-of-type]:mb-0">
<Content /> <Content />
</div> </div>
</div> </div>

View File

@ -27,7 +27,7 @@ const {
/> />
</head> </head>
<body <body
class="bg-global-bg text-global-text mx-auto flex min-h-screen max-w-3xl flex-col px-4 pt-16 font-mono text-sm font-normal antialiased sm:px-8" class="bg-global-bg text-global-text mx-auto flex min-h-screen max-w-5xl flex-col px-4 pt-16 font-mono text-sm font-normal antialiased sm:px-8"
> >
<ThemeProvider /> <ThemeProvider />
<SkipLink /> <SkipLink />

View File

@ -38,14 +38,36 @@ const readingTime: string = remarkPluginFrontmatter.readingTime;
tags: [category, ...tags].join(", "), tags: [category, ...tags].join(", "),
}} }}
> >
<div class="hidden flex-col gap-10 lg:flex lg:flex-row lg:items-start">
{!!headings.length && <TOC headings={headings} classname="lg:w-64 lg:flex-shrink-0" />}
<ArticleContainer className="grow break-words" dataPagefindBody={true}> <ArticleContainer className="grow break-words" dataPagefindBody={true}>
<div id="blog-hero" class="mb-12"> <div id="blog-hero" class="mb-12">
<Masthead content={post} readingTime={readingTime} ogImage={socialImage} /> <Masthead content={post} readingTime={readingTime} ogImage={socialImage} />
</div> </div>
<div class="flex flex-col gap-10 lg:flex-row lg:items-start"> <div class="flex flex-col gap-10 lg:flex-row lg:items-start">
{!!headings.length && <TOC headings={headings} />}
<div <div
class="prose prose-sm prose-headings:font-semibold prose-headings:text-accent-2 prose-headings:before:absolute prose-headings:before:-ms-4 prose-headings:before:text-gray-600 prose-headings:hover:before:text-accent sm:prose-headings:before:content-['#'] sm:prose-th:before:content-none" class="prose prose-base prose-headings:font-semibold prose-headings:text-accent-2 prose-headings:before:absolute prose-headings:before:-ms-4 prose-headings:before:text-gray-600 prose-headings:hover:before:text-accent sm:prose-headings:before:content-['#'] sm:prose-th:before:content-none lg:!max-w-none"
>
<slot />
<WebMentions />
<GiscusComment client:load />
<div class="mt-8 border-t pt-4">
<ShareButtons />
</div>
</div>
</div>
</ArticleContainer>
</div>
<ArticleContainer className="grow break-words lg:hidden" dataPagefindBody={true}>
<div id="blog-hero" class="mb-12">
<Masthead content={post} readingTime={readingTime} ogImage={socialImage} />
</div>
<div class="flex flex-col gap-10 lg:flex-row lg:items-start">
{!!headings.length && <TOC headings={headings} classname="lg:w-64 lg:flex-shrink-0" />}
<div
class="prose prose-base prose-headings:font-semibold prose-headings:text-accent-2 prose-headings:before:absolute prose-headings:before:-ms-4 prose-headings:before:text-gray-600 prose-headings:hover:before:text-accent sm:prose-headings:before:content-['#'] sm:prose-th:before:content-none lg:!max-w-none"
> >
<slot /> <slot />
<WebMentions /> <WebMentions />

View File

@ -10,7 +10,7 @@ const meta = {
<PageLayout meta={meta}> <PageLayout meta={meta}>
<h1 class="title mb-6">About</h1> <h1 class="title mb-6">About</h1>
<div class="prose prose-sm prose-cactus max-w-none">TODO ...</div> <div class="prose prose-base prose-cactus max-w-none">TODO ...</div>
<div class="mt-2"> <div class="mt-2">
<a href="https://wakatime.com/@d3dc2570-e4bf-4469-b0c2-127b495e8b91" <a href="https://wakatime.com/@d3dc2570-e4bf-4469-b0c2-127b495e8b91"
><img ><img