From 05ab51aa05df71edb5b5932cc8933f442b4b5c71 Mon Sep 17 00:00:00 2001 From: Lorenzo Iovino Date: Fri, 9 Jan 2026 18:21:20 +0100 Subject: [PATCH] feat: add navigable table of contents to blog posts --- src/components/TableOfContents.astro | 318 +++++++++++++++++++++++++++ src/content/bio/my-story.mdx | 19 +- src/pages/blog.astro | 3 +- src/pages/blog/[slug].astro | 287 ++++++++++++------------ src/pages/blog/tag/[tag].astro | 2 +- src/styles/global.css | 2 +- src/styles/prose.css | 4 +- 7 files changed, 484 insertions(+), 151 deletions(-) create mode 100644 src/components/TableOfContents.astro diff --git a/src/components/TableOfContents.astro b/src/components/TableOfContents.astro new file mode 100644 index 0000000..035a791 --- /dev/null +++ b/src/components/TableOfContents.astro @@ -0,0 +1,318 @@ +--- +export interface Props { + headings: { depth: number; slug: string; text: string }[]; + variant?: "mobile" | "desktop"; +} + +const { headings, variant = "desktop" } = Astro.props; + +// Filter to only show h2 and h3 +const tocHeadings = headings.filter((h) => h.depth <= 3); +--- + +{ + tocHeadings.length > 0 && ( + <> + {/* Mobile TOC - Sticky Floating Button with Slide-out Panel */} + {variant === "mobile" && ( + <> + {/* Floating Button */} + + + {/* Slide-out Panel Overlay */} +
+ + {/* Slide-out Panel */} +
+
+

+ + + + Table of Contents +

+ +
+ +
+ + )} + + {/* Desktop TOC - Sticky Sidebar */} + {variant === "desktop" && ( + + )} + + ) +} + + + + diff --git a/src/content/bio/my-story.mdx b/src/content/bio/my-story.mdx index 36396c2..f383de4 100644 --- a/src/content/bio/my-story.mdx +++ b/src/content/bio/my-story.mdx @@ -31,7 +31,7 @@ This page is a small recap of my story. Nothing special, just me. ## Childhood Nostalgia
- Super young geek with an Apple II + Super young geek with an Apple II Super young software geek with an Apple II
@@ -44,7 +44,7 @@ I grew up in Ispica, in the south of Sicily. My days were simple: school, videog Ispica is slow, warm, and beautiful. When I was a kid I didn’t see it that way. I wanted to escape. I was dreaming about big cities, more people, more things happening, more opportunities.
- Pokemon Yellow and Game Boy Advance + Pokemon Yellow and Game Boy Advance Pokemon Yellow and Game Boy Advance
@@ -66,7 +66,7 @@ At 17 I also discovered Magic: The Gathering. It became another obsession for a I studied Computer Science at the University of Pisa. It was not a straight path.
- Me burning out studying + Me burning out studying Me burning out studying Computability and Complexity exam
@@ -90,7 +90,7 @@ That period also started my love for traveling. Seeing different cultures in rea ## Embarking on Hackathon Adventures
- Me wearing moverio smart glasses + Me wearing moverio smart glasses Me wearing moverio smart glasses
@@ -112,7 +112,7 @@ That experience made me addicted to hackathons. After that I joined other events ## Erasmus Project in Valencia
- Beautiful sunny day in Valencia + Beautiful sunny day in Valencia Beautiful sunny day in Valencia
@@ -131,7 +131,7 @@ At some point I decided to go back to Sicily. Not as a “I give up” move. More like: I want a different balance.
- Working remote watching the sea + Working remote watching the sea Working remote watching the sea
@@ -148,13 +148,14 @@ Time here feels different. You can actually breathe. You can have “nothing spe Family is a big part of my life here. And I also started a side project with my sister (she’s an agronomist): we planted a small vineyard near the sea and we started producing our own wine. -That project became [www.netum.it](https://netum.it/). It’s small (1 hectare), limited bottles, but it’s something we built together and I love it. -
- The wine produced Zia Lina + The wine produced Zia Lina The wine produced "Zia Lina"
+That project became [www.netum.it](https://netum.it/). It’s small (1 hectare), limited bottles, but it’s something we built together and I love it. + + And yes: food. Sicily is crazy for food. It’s not even a “food culture”, it’s basically a religion. *(No food photos here. I’m not a food blogger. But trust me.)* diff --git a/src/pages/blog.astro b/src/pages/blog.astro index 75ffa69..847f33c 100644 --- a/src/pages/blog.astro +++ b/src/pages/blog.astro @@ -142,7 +142,7 @@ const initialPosts: BlogPost[] = sortedPosts.slice(0, 6); <>
- {post.data.tags.slice(0, 3).map((tag: string) => ( + {post.data.tags.map((tag: string) => (
${post.data.tags - .slice(0, 3) .map( (tag) => `${tag}` diff --git a/src/pages/blog/[slug].astro b/src/pages/blog/[slug].astro index f555d5f..2c06f2e 100644 --- a/src/pages/blog/[slug].astro +++ b/src/pages/blog/[slug].astro @@ -5,6 +5,7 @@ import { Image } from "astro:assets"; import BaseLayout from "../../layouts/BaseLayout.astro"; import Navbar from "../../components/Navbar.astro"; import Footer from "../../components/Footer.astro"; +import TableOfContents from "../../components/TableOfContents.astro"; import "../../styles/prose.css"; import mePhoto from "../../assets/photos/me.png"; @@ -19,7 +20,7 @@ export async function getStaticPaths() { } const { entry }: { entry: BlogPost } = Astro.props; -const { Content } = await entry.render(); +const { Content, headings } = await entry.render(); // Extract image src for meta tags (Open Graph expects a URL string) const heroImageSrc = entry.data.heroImage?.src || mePhoto.src; @@ -36,146 +37,160 @@ const heroImageSrc = entry.data.heroImage?.src || mePhoto.src; >
-
-
- - { - entry.data.tags.length > 0 && ( -
- {entry.data.tags.map((tag: string) => ( - - {tag} - - ))} -
- ) - } -

- {entry.data.title} -

-

- {entry.data.description} -

-
- - { - entry.data.heroImage && ( -
-
- {entry.data.title} -
-
- ) - } - -
-
- -
-
- -
-
- Lorenzo Iovino -
-

- Lorenzo Iovino -

-

- I write software and I also work on a small vineyard in Sicily. In code, trees grow - downward from the root. In real life, trees grow upward from the roots. I spend way - too much time thinking about this. +

+
+
+
+ + { + entry.data.tags.length > 0 && ( +
+ {entry.data.tags.map((tag: string) => ( + + {tag} + + ))} +
+ ) + } +

+ {entry.data.title} +

+

+ {entry.data.description}

-
+ + { + entry.data.heroImage && ( +
+
+ {entry.data.title} +
+
+ ) + } + + +
+ +
+ +
+
+
+ +
+
+ Lorenzo Iovino +
+

+ Lorenzo Iovino +

+

+ I write software and I also work on a small vineyard in Sicily. In code, trees + grow downward from the root. In real life, trees grow upward from the roots. I + spend way too much time thinking about this. +

+ +
+
+
+ + +
+ + +
- - -
+