From 1cd8e7f0d510b97dfc2c3314c36d957383162a8f Mon Sep 17 00:00:00 2001
From: Jacky Zhao <j.zhao2k19@gmail.com>
Date: Sun, 09 Mar 2025 22:06:36 +0000
Subject: [PATCH] feat: support non-singleton table of contents

---
 quartz/components/TableOfContents.tsx   |    7 +++----
 quartz/components/styles/legacyToc.scss |    2 +-
 quartz/components/styles/toc.scss       |    8 ++++----
 quartz/components/scripts/toc.inline.ts |   13 ++++++-------
 4 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/quartz/components/TableOfContents.tsx b/quartz/components/TableOfContents.tsx
index 485f434..da6eece 100644
--- a/quartz/components/TableOfContents.tsx
+++ b/quartz/components/TableOfContents.tsx
@@ -29,8 +29,7 @@
     <div class={classNames(displayClass, "toc")}>
       <button
         type="button"
-        id="toc"
-        class={fileData.collapseToc ? "collapsed" : ""}
+        class={fileData.collapseToc ? "collapsed toc-header" : "toc-header"}
         aria-controls="toc-content"
         aria-expanded={!fileData.collapseToc}
       >
@@ -50,7 +49,7 @@
           <polyline points="6 9 12 15 18 9"></polyline>
         </svg>
       </button>
-      <div id="toc-content" class={fileData.collapseToc ? "collapsed" : ""}>
+      <div class={fileData.collapseToc ? "collapsed toc-content" : "toc-content"}>
         <OverflowList id="toc-ul">
           {fileData.toc.map((tocEntry) => (
             <li key={tocEntry.slug} class={`depth-${tocEntry.depth}`}>
@@ -72,7 +71,7 @@
     return null
   }
   return (
-    <details id="toc" open={!fileData.collapseToc}>
+    <details class="toc" open={!fileData.collapseToc}>
       <summary>
         <h3>{i18n(cfg.locale).components.tableOfContents.title}</h3>
       </summary>
diff --git a/quartz/components/scripts/toc.inline.ts b/quartz/components/scripts/toc.inline.ts
index a518c10..a63da8d 100644
--- a/quartz/components/scripts/toc.inline.ts
+++ b/quartz/components/scripts/toc.inline.ts
@@ -25,16 +25,15 @@
 }
 
 function setupToc() {
-  const toc = document.getElementById("toc")
-  if (toc) {
-    const content = toc.nextElementSibling as HTMLElement | undefined
-    if (!content) return
-    toc.addEventListener("click", toggleToc)
-    window.addCleanup(() => toc.removeEventListener("click", toggleToc))
+  for (const toc of document.querySelectorAll(".toc")) {
+    const button = toc.querySelector(".toc-header")
+    const content = toc.querySelector(".toc-content")
+    if (!button || !content) return
+    button.addEventListener("click", toggleToc)
+    window.addCleanup(() => button.removeEventListener("click", toggleToc))
   }
 }
 
-window.addEventListener("resize", setupToc)
 document.addEventListener("nav", () => {
   setupToc()
 
diff --git a/quartz/components/styles/legacyToc.scss b/quartz/components/styles/legacyToc.scss
index 7a98f34..3513e9f 100644
--- a/quartz/components/styles/legacyToc.scss
+++ b/quartz/components/styles/legacyToc.scss
@@ -1,4 +1,4 @@
-details#toc {
+details.toc {
   & summary {
     cursor: pointer;
 
diff --git a/quartz/components/styles/toc.scss b/quartz/components/styles/toc.scss
index d1feca6..42aa35c 100644
--- a/quartz/components/styles/toc.scss
+++ b/quartz/components/styles/toc.scss
@@ -6,18 +6,18 @@
 
   overflow-y: hidden;
   flex: 0 1 auto;
-  &:has(button#toc.collapsed) {
+  &:has(button.toc-header.collapsed) {
     flex: 0 1 1.2rem;
   }
 }
 
 @media all and not ($mobile) {
-  .toc {
+  .toc-header {
     display: flex;
   }
 }
 
-button#toc {
+button.toc-header {
   background-color: transparent;
   border: none;
   text-align: left;
@@ -44,7 +44,7 @@
   }
 }
 
-#toc-content {
+.toc-content {
   list-style: none;
   position: relative;
 

--
Gitblit v1.10.0