wip toc
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Michael Zhang 2023-09-01 12:38:59 -05:00
parent e94fee5345
commit 3bf0200e7e
7 changed files with 138 additions and 39 deletions

View file

@ -0,0 +1,41 @@
---
import type { MarkdownHeading } from "astro";
import "../styles/toc.scss";
interface Props {
toc: boolean;
headings: MarkdownHeading[];
}
const { toc, headings } = Astro.props;
---
{
toc ? (
<>
<div class="toc-wrapper">
<slot />
<div class="toc">
Table of contents
<ul>
{headings.map((heading) => {
return (
<li>
<a href={`#${heading.slug}`}>{heading.text}</a>
</li>
);
})}
</ul>
</div>
</div>
</>
) : (
<slot />
)
}
<script type="text/javascript">
document.addEventListener("scroll", (doc, evt) => {
console.log("SHIET");
});
</script>

View file

@ -27,6 +27,7 @@ const posts = defineCollection({
tags: z.array(z.string()), tags: z.array(z.string()),
draft: z.boolean().default(false), draft: z.boolean().default(false),
math: z.boolean().default(false), math: z.boolean().default(false),
toc: z.boolean().default(false),
}), }),
}); });

View file

@ -11,6 +11,7 @@ tags:
heroImage: ./header.jpg heroImage: ./header.jpg
heroAlt: gears spinning wallpaper heroAlt: gears spinning wallpaper
math: true math: true
toc: true
--- ---
Back in 2022, I took a special topics course, CSCI 8980, on [reasoning about Back in 2022, I took a special topics course, CSCI 8980, on [reasoning about

View file

@ -4,6 +4,7 @@ import BaseLayout from "../../layouts/BaseLayout.astro";
import { type CollectionEntry, getCollection } from "astro:content"; import { type CollectionEntry, getCollection } from "astro:content";
import Timestamp from "../../components/Timestamp.astro"; import Timestamp from "../../components/Timestamp.astro";
import { getImage } from "astro:assets"; import { getImage } from "astro:assets";
import TocWrapper from "../../components/TocWrapper.astro";
export async function getStaticPaths() { export async function getStaticPaths() {
const posts = await getCollection("posts"); const posts = await getCollection("posts");
@ -16,8 +17,8 @@ export async function getStaticPaths() {
type Props = CollectionEntry<"posts">; type Props = CollectionEntry<"posts">;
const post = Astro.props; const post = Astro.props;
const { Content, remarkPluginFrontmatter } = await post.render(); const { Content, remarkPluginFrontmatter, headings } = await post.render();
const { heroImage: heroImagePath, heroAlt } = post.data; const { toc, heroImage: heroImagePath, heroAlt } = post.data;
let heroImage; let heroImage;
if (heroImagePath) { if (heroImagePath) {
@ -44,44 +45,44 @@ const datestamp = post.data.date.toLocaleDateString(undefined, {
<meta slot="head" property="article:published_time" content={datestamp} /> <meta slot="head" property="article:published_time" content={datestamp} />
<meta slot="head" property="article:author" content="Michael Zhang" /> <meta slot="head" property="article:author" content="Michael Zhang" />
<div class="post-container"> <TocWrapper toc={toc} headings={headings}>
<h1 class="post-title">{post.data.title}</h1> <div class="post-container">
<h1 class="post-title">{post.data.title}</h1>
<span class="tags">
{
post.data.draft && (
<a href="/drafts" class="tag draft">
<i class="fa fa-warning" aria-hidden="true" />
<span class="text">draft</span>
</a>
)
}
{
post.data.tags.map((tag) => (
<a href={`/tags/${tag}`} class="tag">
<i class="fa fa-tag" aria-hidden="true" />
<span class="text">{tag}</span>
</a>
))
}
</span>
<small class="post-meta">
Posted on <Timestamp timestamp={post.data.date} />
- {remarkPluginFrontmatter.minutesRead}
</small>
<span class="tags">
{ {
post.data.draft && ( heroImage && heroAlt && (
<a href="/drafts" class="tag draft"> <div style={`background-image: url(${heroImage.src});`} title={heroAlt} class="hero" />
<i class="fa fa-warning" aria-hidden="true" />
<span class="text">draft</span>
</a>
) )
} }
{ <div class="post-content">
post.data.tags.map((tag) => ( <Content />
<a href={`/tags/${tag}`} class="tag"> </div>
<i class="fa fa-tag" aria-hidden="true" />
<span class="text">{tag}</span>
</a>
))
}
</span>
<small class="post-meta">
Posted on <Timestamp timestamp={post.data.date} />
- {remarkPluginFrontmatter.minutesRead}
</small>
{
heroImage && heroAlt && (
<div style={`background-image: url(${heroImage.src});`} title={heroAlt} class="hero" />
)
}
<!-- <BlogPost {...post.data}> -->
<div class="post-content">
<Content />
</div> </div>
</div> </TocWrapper>
<!-- </BlogPost> -->
</BaseLayout> </BaseLayout>

View file

@ -12,7 +12,6 @@ body {
background-color: var(--background-color); background-color: var(--background-color);
color: var(--text-color); color: var(--text-color);
max-width: 1024px;
margin: auto; margin: auto;
width: 100%; width: 100%;
height: 1px; height: 1px;
@ -94,12 +93,13 @@ pre > code {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: stretch; align-items: stretch;
justify-content: center;
} }
.flex-wrapper > main { .flex-wrapper > main {
min-width: 0; min-width: 0;
box-sizing: border-box; box-sizing: border-box;
padding: 20px; // padding: 20px;
} }
@media screen and (max-width: variables.$breakpoint) { @media screen and (max-width: variables.$breakpoint) {
@ -120,6 +120,6 @@ pre > code {
} }
.flex-wrapper > main { .flex-wrapper > main {
padding-left: 30px; // padding-left: 30px;
} }
} }

View file

@ -1,3 +1,5 @@
@use "variables";
.post-title { .post-title {
font-size: 2rem; font-size: 2rem;
font-weight: 600; font-weight: 600;
@ -20,7 +22,9 @@
} }
.post-container { .post-container {
max-width: 720px;
display: flex; display: flex;
padding: 20px;
flex-direction: column; flex-direction: column;
.toc-drawer { .toc-drawer {
@ -175,6 +179,12 @@
} }
} }
@media screen and (min-width: variables.$breakpoint) {
.post-container {
padding-left: 30px;
}
}
.division .post-content, .division .post-content,
.post-content { .post-content {
.heading { .heading {
@ -210,6 +220,7 @@ hr.endline {
display: flex; display: flex;
gap: 6px; gap: 6px;
margin-bottom: 6px; margin-bottom: 6px;
flex-wrap: wrap;
.tag { .tag {
font-size: 0.75rem; font-size: 0.75rem;

44
src/styles/toc.scss Normal file
View file

@ -0,0 +1,44 @@
@use "variables";
$tocWidth: 180px;
$tocBreakpoint: variables.$breakpoint + $tocWidth;
.toc-wrapper {
position: relative;
display: flex;
}
.toc {
height: 100vh;
ul {
list-style-type: none;
padding-inline-start: 0;
li {
font-size: 14px;
}
}
}
@media screen and (max-width: $tocBreakpoint) {
.toc {
display: none;
}
}
@media screen and (min-width: $tocBreakpoint) {
.article {
flex-grow: 1;
}
.toc {
flex: 0 0 $tocWidth;
max-width: $tocWidth;
position: sticky;
top: 0;
padding: 20px;
overflow-y: auto;
}
}