menu : expand/collapse menu items without navigation #231

This commit is contained in:
Sören Weber 2022-04-03 12:12:12 +02:00
parent cadc808932
commit 48c7d6bc73
No known key found for this signature in database
GPG key ID: 07D17FF580AE7589
12 changed files with 133 additions and 52 deletions

View file

@ -31,6 +31,7 @@ title = "Hugo Relearn Documentation"
description = "Documentation for Hugo Relearn Theme"
author = "Sören Weber"
showVisitedLinks = true
collapsibleMenu = true
disableBreadcrumb = false
disableNextPrev = false
disableLandingPageButton = true

View file

@ -70,6 +70,8 @@ Note that some of these parameters are explained in details in other sections of
custom_css = ["css/foo.css", "css/bar.css"]
# Change the title separator. Default to "::".
titleSeparator = "-"
# If set to true, the menu in the sidebar will be displayed in a collapsible tree view.
collapsibleMenu = false
```
## A word on running your site in a subfolder

View file

@ -18,6 +18,8 @@ This document shows you what's new in the latest release. For a detailed list of
- **Breaking**: If you had previously overwritten the `custom-footer.html` partial to add visual elements below the content of your page, you have to move this content to the new partial `content-footer.html`. `custom-footer.html` was never meant to contain HTML other than additional styles and JavaScript.
- **New**: If you prefer expandable/collapsible menu items, you can now set `collapsibleMenu=true` in your `config.toml`. This will add arrows to all menu items that contain sub menus. The menu will expand/collapse without navigation if you click on an arrow.
- **New**: You can activate [print support]({{%relref "basics/configuration#activate-print-support" %}}) in your `config.toml` to add the capability to print whole chapters or even the complete site.
---

View file

@ -1,5 +1,5 @@
+++
alwaysopen = false
alwaysopen = true
description = "This is a demo child page"
tags = ["children", "non-hidden"]
title = "page 1-1"

View file

@ -1,5 +1,5 @@
+++
alwaysopen = false
alwaysopen = true
descrption = "This be a demo child plank"
tags = ["children", "non-hidden"]
title = "Plank 1-1"

View file

@ -1,8 +1,8 @@
{{- $isActive := .IsHome }}
{{- $currentNode := . }}
{{- $isActive := .IsHome }}
{{- $pages := .Site.Home.Sections }}
{{- $defaultOrdersectionsby := .Site.Params.ordersectionsby | default "weight" }}
{{- $currentOrdersectionsby := .Site.Home.Params.ordersectionsby | default $defaultOrdersectionsby }}
{{- $pages := .Site.Home.Sections }}
{{- if $isActive }}
{{- template "section-print" dict "sect" . "currentnode" $currentNode }}
{{- if or .IsHome .Params.chapter $pages }}
@ -24,24 +24,24 @@
{{- end }}
{{- end }}
{{- define "section-tree-print" }}
{{- $isActive := .isActive }}
{{- $currentNode := .currentnode }}
{{- $isActive := .isActive }}
{{- $currentFileRelPermalink := .currentnode.RelPermalink }}
{{- with .sect }}
{{- $currentIsActive := eq .RelPermalink $currentFileRelPermalink }}
{{- $isActive = or $currentIsActive $isActive }}
{{- $relearnIsHiddenFrom := index ($currentNode.Scratch.Get "relearnIsHiddenFrom") .RelPermalink }}
{{- $hidden := and $relearnIsHiddenFrom (not $.showhidden) (not (.IsAncestor $currentNode)) }}
{{- if $hidden }}
{{- else if or .IsSection .IsHome }}
{{- $defaultOrdersectionsby := .Site.Params.ordersectionsby | default "weight" }}
{{- $currentOrdersectionsby := .Params.ordersectionsby | default $defaultOrdersectionsby }}
{{- $pages := .Pages }}
{{- if .Page.IsHome }}
{{- $pages = .Sections }}
{{- else if .Page.Sections}}
{{- $pages = (.Pages | union .Sections) }}
{{- end }}
{{- $relearnIsHiddenFrom := index ($currentNode.Scratch.Get "relearnIsHiddenFrom") .RelPermalink }}
{{- $hidden := and $relearnIsHiddenFrom (not $.showhidden) (not (.IsAncestor $currentNode)) }}
{{- if $hidden }}
{{- else if or .IsSection .IsHome }}
{{- $defaultOrdersectionsby := .Site.Params.ordersectionsby | default "weight" }}
{{- $currentOrdersectionsby := .Params.ordersectionsby | default $defaultOrdersectionsby }}
{{- if $isActive }}
{{- template "section-print" dict "sect" . "currentnode" $currentNode }}
{{- if or .IsHome .Params.chapter $pages }}

View file

@ -20,7 +20,7 @@
</div>
{{- end }}
<div id="content-wrapper" class="highlightable">
<ul class="topics">
<ul class="topics{{ if .Site.Params.collapsibleMenu }} collapsible-menu{{ end }}">
{{- $defaultOrdersectionsby := .Site.Params.ordersectionsby | default "weight" }}
{{- $currentOrdersectionsby := .Site.Home.Params.ordersectionsby | default $defaultOrdersectionsby }}
{{- $defaultAlwaysopen := .Site.Params.alwaysopen | default false }}
@ -111,28 +111,38 @@
</div>
</aside>
{{- define "section-tree-nav" }}
{{- $showvisitedlinks := .showvisitedlinks }}
{{- $currentNode := .currentnode }}
{{- $currentFileRelPermalink := .currentnode.RelPermalink }}
{{- $showvisitedlinks := .showvisitedlinks }}
{{- $alwaysopen := .alwaysopen }}
{{- $currentFileRelPermalink := .currentnode.RelPermalink }}
{{- with .sect }}
{{- $relearnIsHiddenFrom := index ($currentNode.Scratch.Get "relearnIsHiddenFrom") .RelPermalink }}
{{- $hidden := and $relearnIsHiddenFrom (not $.showhidden) (not (.IsAncestor $currentNode)) }}
{{- if $hidden }}
{{- else if .IsSection }}
{{- safeHTML .Params.head }}
{{- $defaultOrdersectionsby := .Site.Params.ordersectionsby | default "weight" }}
{{- $currentOrdersectionsby := .Params.ordersectionsby | default $defaultOrdersectionsby }}
{{- $currentAlwaysopen := .Params.alwaysopen | default $alwaysopen }}
<li data-nav-id="{{.RelPermalink}}" title="{{.Title}}" class="dd-item{{if eq .RelPermalink $currentFileRelPermalink}} active{{end}}{{if .IsAncestor $currentNode }} parent{{end}}{{if $currentAlwaysopen}} alwaysopen{{end}}"><a href="{{.RelPermalink}}">
{{- partial "menu-pre.html" . }}{{ or .Params.menuTitle .LinkTitle .Title }}{{ partial "menu-post.html" . }}
{{- if $showvisitedlinks }}<i class="fas fa-check read-icon"></i>{{ end }}</a><ul>
{{- $isActive := eq .RelPermalink $currentFileRelPermalink }}
{{- $pages := .Pages }}
{{- if .Page.IsHome }}
{{- $pages = .Sections }}
{{- else if .Page.Sections}}
{{- $pages = (.Pages | union .Sections) }}
{{- end }}
{{- $relearnIsHiddenFrom := index ($currentNode.Scratch.Get "relearnIsHiddenFrom") .RelPermalink }}
{{- $hidden := and $relearnIsHiddenFrom (not $.showhidden) (not (.IsAncestor $currentNode)) }}
{{- if $hidden }}
{{- else if or .IsSection .IsHome }}
{{- $numberOfVisibleChildren := 0 }}
{{- range $pages }}
{{- $relearnIsSubHiddenFrom := index ($currentNode.Scratch.Get "relearnIsHiddenFrom") .RelPermalink }}
{{- $subHidden := and $relearnIsSubHiddenFrom (not $.showhidden) (not (.IsAncestor $currentNode)) }}
{{- $numberOfVisibleChildren = add $numberOfVisibleChildren (int (not $subHidden)) }}
{{- end }}
{{- safeHTML .Params.head }}
{{- if $numberOfVisibleChildren }}
{{- $defaultOrdersectionsby := .Site.Params.ordersectionsby | default "weight" }}
{{- $currentOrdersectionsby := .Params.ordersectionsby | default $defaultOrdersectionsby }}
{{- $currentAlwaysopen := .Params.alwaysopen | default $alwaysopen }}
{{- $pageHash := md5 .Page }}
{{- $isOpen := or $currentAlwaysopen (.IsAncestor $currentNode) }}
<li data-nav-id="{{.RelPermalink}}" title="{{.Title}}" class="dd-item{{if $isActive }} active{{end}}{{if .IsAncestor $currentNode }} parent{{end}}{{if $currentAlwaysopen}} alwaysopen{{end}}"><input type="checkbox" id="section-{{ $pageHash }}" class="toggle"{{ if $isOpen }} checked{{ end }}/><label for="section-{{ $pageHash }}" ></label><a href="{{.RelPermalink}}">
{{- partial "menu-pre.html" . }}{{ or .Params.menuTitle .LinkTitle .Title }}{{ partial "menu-post.html" . }}
{{- if $showvisitedlinks }}<i class="fas fa-check read-icon"></i>{{ end }}</a><ul>
{{- $defaultAlwaysopen := .Site.Params.alwaysopen | default true }}
{{- if eq $currentOrdersectionsby "title" }}
{{- range $pages.ByTitle }}
@ -144,7 +154,12 @@
{{- end }}
{{- end }}</ul></li>
{{- else }}
<li data-nav-id="{{.RelPermalink}}" title="{{.Title}}" class="dd-item{{if eq .RelPermalink $currentFileRelPermalink}} active{{end}}"><a href="{{.RelPermalink}}">
<li data-nav-id="{{.RelPermalink}}" title="{{.Title}}" class="dd-item{{if $isActive }} active{{end}}"><a href="{{.RelPermalink}}">
{{- partial "menu-pre.html" . }}{{ or .Params.menuTitle .LinkTitle .Title }}{{ partial "menu-post.html" . }}
{{- if $showvisitedlinks }}<i class="fas fa-check read-icon"></i>{{ end }}</a></li>
{{- end }}
{{- else }}
<li data-nav-id="{{.RelPermalink}}" title="{{.Title}}" class="dd-item{{if $isActive }} active{{end}}"><a href="{{.RelPermalink}}">
{{- partial "menu-pre.html" . }}{{ or .Params.menuTitle .LinkTitle .Title }}{{ partial "menu-post.html" . }}
{{- if $showvisitedlinks }}<i class="fas fa-check read-icon"></i>{{ end }}</a></li>
{{- end }}

View file

@ -3,9 +3,9 @@
{{- $currentNode.Scratch.Delete "relearnPrevPage" }}
{{- $currentNode.Scratch.Delete "relearnNextPage" }}
{{- $currentNode.Scratch.Delete "relearnSubPages" }}
{{- $currentNode.Scratch.Delete "relearnIsHiddenNode" }}
{{- $currentNode.Scratch.Delete "relearnIsHiddenStem" }}
{{- $currentNode.Scratch.Delete "relearnIsHiddenFrom" }}
{{- $currentNode.Scratch.Delete "relearnIsHiddenNode" }}{{/* the node itself is flagged as hidden */}}
{{- $currentNode.Scratch.Delete "relearnIsHiddenStem" }}{{/* the node or one of its parents is flagged as hidden */}}
{{- $currentNode.Scratch.Delete "relearnIsHiddenFrom" }}{{/* the node is hidden from the current page */}}
{{- template "relearn-structure" dict "node" .Site.Home "currentnode" $currentNode "hiddenstem" false "hiddencurrent" false "defaultOrdersectionsby" .Site.Params.ordersectionsby }}
{{- define "relearn-structure" }}
{{- $currentNode := .currentnode }}

View file

@ -157,7 +157,8 @@ body h6 {
0 0 10px var(--INTERNAL-MAIN-TITLES-H5-color);
}
body #sidebar ul li.active > a {
body #sidebar ul.topics li.active > label,
body #sidebar ul.topics li.active > a {
color: #fff;
text-shadow:
0 0 1px #fff,
@ -168,6 +169,7 @@ body #sidebar ul li.active > a {
}
body #sidebar select:hover,
body #sidebar label:hover,
body #sidebar a:hover {
color: #fff;
text-shadow:

View file

@ -190,11 +190,13 @@ th {
z-index: 410;
}
#sidebar .collapsible-menu label:after,
#sidebar a {
color: #bababa; /* var(--MENU-SECTIONS-LINK-color) */
}
#sidebar select:hover,
#sidebar .collapsible-menu label:hover:after,
#sidebar a:hover {
color: #ffffff; /* var(--MENU-SECTIONS-LINK-HOVER-color) */
}
@ -203,12 +205,6 @@ th {
padding: 0 1rem;
}
#sidebar ul {
list-style: none;
padding: 0;
margin: 0;
}
#sidebar ul.topics {
margin: 0 1rem;
}
@ -221,6 +217,10 @@ th {
display: none;
}
#sidebar ul.topics li {
position: relative;
}
#sidebar ul.topics > li > ul > li:last-child {
padding-bottom: 1rem;
}
@ -235,6 +235,12 @@ th {
display: block;
}
#sidebar ul.topics input.toggle,
#sidebar ul.topics label {
display: none;
}
#sidebar ul.topics > li > label,
#sidebar ul.topics > li > a {
font-size: 1.1rem;
line-height: 2rem;
@ -249,23 +255,35 @@ th {
margin-top: 9px;
}
#sidebar ul.topics > li.parent {
background-color: rgba( 0, 0, 0, .166 ); /* var(--MENU-SECTIONS-ACTIVE-BG-color) */
#sidebar ul.topics > li {
margin-left: -1rem;
margin-right: -1rem;
padding-left: 1rem;
padding-right: 1rem;
}
#sidebar ul li.active > a {
background-color: #ffffff; /* var(--MENU-SECTION-ACTIVE-CATEGORY-BG-color) */
color: #444444; /* var(--MENU-SECTION-ACTIVE-CATEGORY-color) */
#sidebar ul.topics > li.parent {
background-color: rgba( 0, 0, 0, .166 ); /* var(--MENU-SECTIONS-ACTIVE-BG-color) */
}
#sidebar ul.topics li > a {
margin-left: -1rem;
margin-right: -1rem;
padding-left: 1rem;
padding-right: 1rem;
}
#sidebar ul.topics li.active > a {
background-color: #ffffff; /* var(--MENU-SECTION-ACTIVE-CATEGORY-BG-color) */
color: #444444; /* var(--MENU-SECTION-ACTIVE-CATEGORY-color) */
}
#sidebar ul {
list-style: none;
padding: 0;
margin: 0;
}
#sidebar ul li {
padding: 0;
}
@ -298,12 +316,6 @@ th {
margin-top: 9px;
}
#sidebar ul {
list-style: none;
margin: 0;
padding: 0;
}
#sidebar #shortcuts li {
list-style: none;
padding: 2px 0;
@ -1573,3 +1585,39 @@ input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration { display: none; }
#sidebar ul.collapsible-menu input.toggle {
cursor: pointer;
display: block;
left: -1rem;
opacity: 0;
overflow: hidden;
position: absolute;
top: 0;
}
#sidebar ul.collapsible-menu label {
cursor: pointer;
display: inline;
height: 1rem;
left: 0;
margin-top: .25em;
position: absolute;
width: 1rem;
}
#sidebar .collapsible-menu input.toggle + label:after {
content: "▸";
}
#sidebar .collapsible-menu input.toggle:checked + label:after {
content: "▾";
}
#sidebar .collapsible-menu input.toggle + label + a + ul {
display: none;
}
#sidebar .collapsible-menu input.toggle:checked + label + a + ul {
display: inline;
}

View file

@ -121,11 +121,13 @@ a:hover,
background-color: var(--INTERNAL-MENU-SEARCH-BG-color);
}
#sidebar .collapsible-menu label:after,
#sidebar a {
color: var(--INTERNAL-MENU-SECTIONS-LINK-color);
}
#sidebar select:hover,
#sidebar .collapsible-menu label:hover:after,
#sidebar a:hover {
color: var(--INTERNAL-MENU-SECTIONS-LINK-HOVER-color);
}
@ -135,7 +137,7 @@ a:hover,
background-color: var(--INTERNAL-MENU-SECTIONS-ACTIVE-BG-color);
}
#sidebar ul li.active > a {
#sidebar ul.topics li.active > a {
background-color: var(--INTERNAL-MENU-SECTION-ACTIVE-CATEGORY-BG-color);
color: var(--INTERNAL-MENU-SECTION-ACTIVE-CATEGORY-color);
}

View file

@ -339,10 +339,6 @@ function initMenuScrollbar(){
// that need to be executed inbetween our own handlers
var psm = new PerfectScrollbar('#content-wrapper');
var psc = new PerfectScrollbar(content);
window.addEventListener('resize', function(){
psm && psm.update();
psc && psc.update();
});
document.addEventListener('keydown', function(){
// if we facked initial scrolling, we want to
// remove the focus to not leave visual markers on
@ -353,6 +349,19 @@ function initMenuScrollbar(){
autofocus = false;
}
});
// on resize, we have to redraw the scrollbars to let new height
// affect their size
window.addEventListener('resize', function(){
psm && psm.update();
psc && psc.update();
});
// now that we may have collapsible menus, we need to call a resize
// for the menu scrollbar if sections are expanded/collapsed
document.querySelectorAll('#sidebar .collapsible-menu input.toggle').forEach( function(e){
e.addEventListener('change', function(){
psm && psm.update();
});
});
}
function initLightbox(){