feat: add collapsible table of contents for smaller screens (#1245)

* refactor: create partial/article/components/toc

* feat: add collapsible table of contents for smaller screens
This commit is contained in:
Jimmy
2026-01-26 22:28:27 +01:00
committed by GitHub
parent 3a03d69502
commit 0f33b3efb7
4 changed files with 157 additions and 72 deletions
+88 -27
View File
@@ -84,20 +84,7 @@
} }
} }
.widget--toc { .toc-nav {
background-color: var(--card-background);
border-radius: var(--card-border-radius);
box-shadow: var(--shadow-l1);
display: flex;
flex-direction: column;
color: var(--card-text-color-main);
overflow: hidden;
::-webkit-scrollbar-thumb {
background-color: var(--card-separator-color);
}
#TableOfContents {
overflow-x: auto; overflow-x: auto;
max-height: 75vh; max-height: 75vh;
@@ -119,7 +106,7 @@
} }
} }
& > ul { &>ul {
padding: 0 1em; padding: 0 1em;
} }
@@ -127,49 +114,119 @@
margin: 15px 0 15px 20px; margin: 15px 0 15px 20px;
padding: 5px; padding: 5px;
& > ol, &>ol,
& > ul { &>ul {
margin-top: 10px; margin-top: 10px;
padding-left: 10px; padding-left: 10px;
margin-bottom: -5px; margin-bottom: -5px;
& > li:last-child { &>li:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
} }
} }
li.active-class > a {
li.active-class>a {
border-left: var(--heading-border-size) solid var(--accent-color); border-left: var(--heading-border-size) solid var(--accent-color);
font-weight: bold; font-weight: bold;
} }
ul li.active-class > a { ul li.active-class>a {
display: block; display: block;
} }
@function repeat($str, $n) { @function repeat($str, $n) {
$result: ""; $result: "";
@for $_ from 0 to $n { @for $_ from 0 to $n {
$result: $result + $str; $result: $result + $str;
} }
@return $result; @return $result;
} }
// Support up to 6 levels of indentation for lists in ToCs // Support up to 6 levels of indentation for lists in ToCs
@for $i from 0 to 5 { @for $i from 0 to 5 {
& > ul #{repeat("> li > ul", $i)} > li.active-class > a { &>ul #{repeat("> li > ul", $i)}>li.active-class>a {
$n: 25 + $i * 35; $n: 25 + $i * 35;
margin-left: calc(-#{$n}px - 1em); margin-left: calc(-#{$n}px - 1em);
padding-left: calc(#{$n}px + 1em - var(--heading-border-size)); padding-left: calc(#{$n}px + 1em - var(--heading-border-size));
} }
& > ol #{repeat("> li > ol", $i)} > li.active-class > a { &>ol #{repeat("> li > ol", $i)}>li.active-class>a {
$n: 9 + $i * 35; $n: 9 + $i * 35;
margin-left: calc(-#{$n}px - 1em); margin-left: calc(-#{$n}px - 1em);
padding-left: calc(#{$n}px + 1em - var(--heading-border-size)); padding-left: calc(#{$n}px + 1em - var(--heading-border-size));
display: block; display: block;
} }
} }
}
.widget--toc,
.article-toc {
display: flex;
flex-direction: column;
color: var(--card-text-color-main);
::-webkit-scrollbar-thumb {
background-color: var(--card-separator-color);
}
}
.widget--toc {
background-color: var(--card-background);
border-radius: var(--card-border-radius);
box-shadow: var(--shadow-l1);
overflow: hidden;
}
.article-toc {
padding: 0 var(--card-padding);
margin-top: 20px;
@include respond(lg) {
display: none;
}
details {
background-color: var(--card-background);
border-radius: var(--card-border-radius);
box-shadow: var(--shadow-l2);
&[open] {
.article-toc-title {
svg {
transform: rotate(90deg);
}
}
}
summary {
list-style: none;
padding: 15px 20px;
cursor: pointer;
&::-webkit-details-marker {
display: none;
}
.article-toc-title {
display: flex;
align-items: center;
gap: 10px;
text-transform: uppercase;
font-size: 1.4rem;
font-weight: bold;
color: var(--card-text-color-tertiary);
svg {
width: 20px;
height: 20px;
stroke-width: 1.33;
transition: transform 0.3s ease;
}
}
}
} }
} }
@@ -177,7 +234,7 @@
overflow-x: auto; overflow-x: auto;
padding-bottom: 15px; padding-bottom: 15px;
& > .flex { &>.flex {
float: left; float: left;
} }
@@ -208,7 +265,7 @@
padding: 0 var(--card-padding); padding: 0 var(--card-padding);
line-height: var(--article-line-height); line-height: var(--article-line-height);
& > p { &>p {
margin: 1.5em 0; margin: 1.5em 0;
} }
@@ -316,10 +373,12 @@
line-height: 1.428571429; line-height: 1.428571429;
word-break: break-all; word-break: break-all;
padding: var(--card-padding); padding: var(--card-padding);
// keep Codeblocks LTR // keep Codeblocks LTR
[dir="rtl"] & { [dir="rtl"] & {
direction: ltr; direction: ltr;
} }
code { code {
color: unset; color: unset;
border: none; border: none;
@@ -338,10 +397,12 @@
opacity: 1; opacity: 1;
} }
} }
// keep Codeblocks LTR // keep Codeblocks LTR
[dir="rtl"] & { [dir="rtl"] & {
direction: ltr; direction: ltr;
} }
pre { pre {
margin: initial; margin: initial;
padding: 0; padding: 0;
@@ -406,8 +467,8 @@
padding-bottom: 56.25%; padding-bottom: 56.25%;
overflow: hidden; overflow: hidden;
& > iframe, &>iframe,
& > video { &>video {
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -444,7 +505,7 @@
} }
/// Make long KaTeX equations scrollable in the x-axis /// Make long KaTeX equations scrollable in the x-axis
.katex-display > .katex { .katex-display>.katex {
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
} }
+16
View File
@@ -1,6 +1,22 @@
<article class="{{ if .Params.image }}has-image {{ end }}main-article"> <article class="{{ if .Params.image }}has-image {{ end }}main-article">
{{ partial "article/components/header" . }} {{ partial "article/components/header" . }}
{{ if .Scratch.Get "TOCEnabled" }}
<aside class="article-toc">
<details>
<summary>
<div class="article-toc-title">
{{ partial "helper/icon" "chevron-right" }}
<span>{{ T "article.tableOfContents" }}</span>
</div>
</summary>
<nav class="toc-nav">
{{ partial "article/components/toc" . | safeHTML }}
</nav>
</details>
</aside>
{{ end }}
{{ partial "article/components/content" . }} {{ partial "article/components/content" . }}
{{ partial "article/components/footer" . }} {{ partial "article/components/footer" . }}
@@ -0,0 +1,6 @@
{{/* Remove <nav id="TableOfContents"> and </nav> from .TableOfContents */}}
{{ $toc := .TableOfContents }}
{{ $toc = replace $toc "<nav id=\"TableOfContents\">" "" }}
{{ $toc = replace $toc "</nav>" "" }}
{{ return $toc }}
+3 -1
View File
@@ -6,7 +6,9 @@
<h2 class="widget-title section-title">{{ T "article.tableOfContents" }}</h2> <h2 class="widget-title section-title">{{ T "article.tableOfContents" }}</h2>
<div class="widget--toc"> <div class="widget--toc">
{{ .Context.TableOfContents }} <nav class="toc-nav" id="TableOfContents">
{{ partial "article/components/toc" .Context | safeHTML }}
</nav>
</div> </div>
</section> </section>
{{ end }} {{ end }}