Implement folding for the TOC sidebar

dkasak/foldable-sidebar
Denis Kasak 3 months ago
parent 76e1426f92
commit 32854cc980

@ -524,3 +524,98 @@ nav.foldable-nav {
margin: initial;
}
}
// Fix some visual bugs regarding sidebar_menu_foldable / foldable-nav support
// and extend it to ordered lists
nav.foldable-nav {
.with-child ol {
list-style: none;
padding: 0;
margin: 0;
}
.ol-1 > li {
padding-left: 1.5em;
}
ol.foldable {
max-height: 0;
overflow: hidden;
}
input:checked ~ ol.foldable {
max-height: 100vmax;
}
.ol-1 .with-child > label:before {
display: inline-block;
font-family: inherit;
font-style: normal;
font-variant: normal;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
font-weight: 900; content: "+";
position: absolute;
left: 0.1em;
padding-left: 0.4em;
padding-right: 0.4em;
font-size: 1em;
color: $gray-900;
transform: unset;
transition: unset;
}
.ol-1 .with-child > input:checked ~ label:before {
color: $gray-900;
content: "-";
transform: unset;
transition: unset;
}
.with-child ol { margin-top: 0.1em; }
/* Fix bugs and annoyances with unordered lists */
.ul-1 .with-child > label:before {
font-weight: 900; content: "+";
font-family: inherit;
transform: unset;
transition: unset;
}
.ul-1 .with-child > input:checked ~ label:before {
color: $gray-900;
content: "-";
transform: unset;
transition: unset;
}
}
@media (hover: hover) and (pointer: fine) {
nav.foldable-nav {
.ul-1 .with-child > label:hover:before {
color: $gray-900;
transform: unset;
transition: unset;
}
.ul-1 .with-child > input:checked ~ label:hover:before {
color: $gray-900;
transform: unset;
transition: unset;
}
.ol-1 .with-child > label:hover:before {
color: $gray-900;
transform: unset;
transition: unset;
}
.ol-1 .with-child > input:checked ~ label:hover:before {
color: $gray-900;
transform: unset;
transition: unset;
}
}
}

@ -107,9 +107,10 @@ function makeToc() {
// we have to adjust heading IDs to ensure that they are unique
const nav = document.createElement("nav");
nav.classList.add("td-sidebar-nav", "foldable-nav");
nav.id = "TableOfContents";
const section = makeTocSection(tocTargets, 0);
const section = makeTocSection(tocTargets, 0, 1);
nav.appendChild(section.content);
// build the TOC and append to it title and content
const toc = document.createElement("div");
@ -130,10 +131,24 @@ function makeToc() {
// create a single ToC entry
function makeTocEntry(heading) {
const li = document.createElement("li");
li.classList.add("td-sidebar-nav__section-title", "td-sidebar-nav__section");
const input = document.createElement("input");
input.setAttribute("id", `toc-${heading.id}-check`);
input.setAttribute("type", "checkbox");
const label = document.createElement("label");
label.setAttribute("for", `toc-${heading.id}-check`);
const a = document.createElement("a");
a.setAttribute("href", `#${heading.id}`);
a.setAttribute("id", `toc-${heading.id}`);
a.classList.add("td-sidebar-link", "td-sidebar-link__page");
a.textContent = heading.textContent;
li.appendChild(a);
li.appendChild(input);
li.appendChild(label);
label.appendChild(a);
return li;
}
@ -142,8 +157,9 @@ Each ToC section is an `<ol>` element.
ToC entries are `<li>` elements and these contain nested ToC sections,
whenever we go to the next heading level down.
*/
function makeTocSection(headings, index) {
function makeTocSection(headings, index, depth) {
const ol = document.createElement("ol");
ol.classList.add("td-sidebar-nav__section", `ol-${depth}`);
let previousHeading = null;
let previousLi = null;
let i = index;
@ -152,13 +168,20 @@ function makeTocSection(headings, index) {
const thisHeading = headings[i];
if (previousHeading && (thisHeading.tagName > previousHeading.tagName)) {
// we are going down a heading level, create a new nested section
const section = makeTocSection(headings, i);
const section = makeTocSection(headings, i, depth+1);
previousLi.appendChild(section.content);
i = section.index -1;
if (depth >= 1) {
section.content.classList.add("foldable");
}
previousLi.classList.add("with-child");
i = section.index - 1;
}
else if (previousHeading && (previousHeading.tagName > thisHeading.tagName)) {
// we have come back up a level, so a section is finished
for (let li of lis) {
if (!li.classList.contains("with-child")) {
li.classList.add("without-child");
}
ol.appendChild(li);
}
return {
@ -174,6 +197,9 @@ function makeTocSection(headings, index) {
}
}
for (let li of lis) {
if (!li.classList.contains("with-child")) {
li.classList.add("without-child");
}
ol.appendChild(li);
}
return {

Loading…
Cancel
Save