Skip to content

Commit 7bd70ff

Browse files
committed
Provide mobile toc
Closes gh-2
1 parent 449152b commit 7bd70ff

File tree

8 files changed

+137
-30
lines changed

8 files changed

+137
-30
lines changed

src/main/css/asciidoctor.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@
120120
font-weight: var(--asciidoctor-heading-font-weight);
121121
hyphens: none;
122122
line-height: 1.3;
123-
margin: 2.5rem 0 0;
123+
margin: 1.3rem 0 0;
124+
padding-top: 1.8rem;
124125
}
125126

126127
.doc h1.sect0 {
@@ -131,13 +132,13 @@
131132
}
132133

133134
.doc h1:first-child {
134-
margin: 1.5rem 0;
135+
margin: 1.3rem 0;
135136
}
136137

137138
.doc h2:not(.discrete) {
138139
margin-left: -1rem;
139140
margin-right: -1rem;
140-
padding: 0.4rem 1rem 0.1rem;
141+
padding: 1.8rem 1rem 0.1rem;
141142
}
142143

143144
.doc h3:not(.discrete) {

src/main/css/layout.css

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222

2323
#banner {
2424
height: 100%;
25-
background: var(--layout-banner-logo) no-repeat top 18px left 18px / auto
26-
calc(var(--layout-banner-height) - 30px);
25+
background: var(--layout-banner-logo) no-repeat top
26+
var(--layout-banner-logo-offset) left var(--layout-banner-logo-offset) /
27+
auto var(--layout-banner-logo-height);
2728
}
2829

2930
#doc {
@@ -35,10 +36,6 @@
3536
margin: 0 auto;
3637
}
3738

38-
#navbar-container {
39-
display: none;
40-
}
41-
4239
div#switch-theme,
4340
#switch-theme label {
4441
display: none;

src/main/css/settings-dark.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ html.dark-theme {
5454

5555
/* TOC */
5656
--toc-back-to-index-filter: invert();
57+
--toc-bar-button-filter: invert();
5758

5859
/* Code Tools */
5960
--codetools-button-filter: invert();

src/main/css/settings.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242

4343
/* Layout */
4444
--layout-banner-logo: url("../img/banner-logo.svg");
45+
--layout-banner-logo-offset: 18px;
46+
--layout-banner-logo-height: 50px;
4547
--layout-max-width: 1400px;
4648
--layout-banner-height: 80px;
4749
--layout-border-color: var(--color-accent-1);
@@ -139,6 +141,9 @@
139141
--toc-active-background-color: var(--selected-background-color);
140142
--toc-active-font-color: var(--body-background-color);
141143
--toc-back-to-index-filter: none;
144+
--toc-bar-display: none;
145+
--toc-bar-height: 0;
146+
--toc-bar-button-filter: none;
142147

143148
/* Code Tools */
144149
--codetools-button-filter: none;
@@ -164,6 +169,12 @@
164169

165170
@media screen and (max-width: 800px) {
166171
:root {
172+
--layout-banner-height: 51px;
173+
--layout-banner-logo-height: 30px;
174+
--layout-banner-logo-offset: 10px;
175+
--layout-border-color: var(--body-background-color);
176+
--toc-bar-display: block;
177+
--toc-bar-height: 24px;
167178
--toc-width: 0;
168179
--toc-display: none;
169180
--asciidoctor-doc-embellishment-background: none;

src/main/css/toc.css

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ body.toc-left #doc {
6363
background-color: var(--toc-hover-background-color);
6464
}
6565

66-
#toc.fixed-toc {
66+
body.fixed-toc #toc {
6767
position: fixed;
6868
top: 0;
6969
overflow-x: scroll;
@@ -109,3 +109,61 @@ body.toc-left #doc {
109109
min-height: 16px;
110110
left: 1.4rem;
111111
}
112+
113+
#tocbar-container {
114+
display: var(--toc-bar-display);
115+
width: 100%;
116+
}
117+
118+
#tocbar-container {
119+
height: var(--tocbar-height);
120+
background-color: var(--body-background-color);
121+
border-bottom: 1px solid var(--panel-border-color);
122+
z-index: 10000;
123+
}
124+
125+
#tocbar {
126+
width: 100%;
127+
height: 100%;
128+
padding-left: 6px;
129+
}
130+
131+
body.fixed-toc #tocbar-container {
132+
position: fixed;
133+
top: 0;
134+
}
135+
136+
button#toggle-toc {
137+
width: var(--toc-bar-height);
138+
height: var(--toc-bar-height);
139+
filter: var(--toc-bar-button-filter);
140+
background: no-repeat center / 16px 16px;
141+
background-image: url("../img/octicons-16.svg#view-three-bars");
142+
border: none;
143+
outline: none;
144+
padding: 0;
145+
display: block;
146+
}
147+
148+
body.show-toc button#toggle-toc {
149+
background-image: url("../img/octicons-16.svg#view-x");
150+
}
151+
152+
@media screen and (max-width: 800px) {
153+
body.fixed-toc #toc {
154+
top: var(--toc-bar-height);
155+
}
156+
157+
#toc {
158+
top: calc(var(--layout-banner-height) + var(--toc-bar-height));
159+
width: 100%;
160+
height: 100%;
161+
left: 0;
162+
background-color: var(--body-background-color);
163+
z-index: 10000;
164+
}
165+
166+
body.show-toc #toc {
167+
display: block;
168+
}
169+
}

src/main/img/octicons-16.svg

Lines changed: 15 additions & 3 deletions
Loading

src/main/js/site/toc.js

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
const debugMode = false;
2424

2525
const tocElement = document.querySelector("#toc");
26+
const toggleTocElement = document.querySelector("#toggle-toc");
2627
const contentElement = document.querySelector("#content");
2728

2829
if (!tocElement || !contentElement) {
@@ -33,11 +34,11 @@
3334
const hrefToTocAnchorElement = buildHrefToTocAnchorElement();
3435
const headingElementToTocElement = buildHeadingElementToTocElement();
3536

36-
let fixedPositionTop = null;
3737
let lastActiveTocElement = null;
3838
let disableOnScroll = false;
3939

4040
tocElement.addEventListener("click", onTocElementClick);
41+
toggleTocElement.addEventListener("click", onToggleTocClick);
4142
window.addEventListener("load", onLoad);
4243

4344
function findHeadingElements() {
@@ -105,6 +106,7 @@
105106
window.addEventListener("hashchange", onLocationHashChange);
106107
window.addEventListener("scroll", onScroll);
107108
window.addEventListener("scroll", onEndScroll);
109+
window.addEventListener("resize", onResize);
108110
}
109111

110112
function onLocationHashChange() {
@@ -119,12 +121,16 @@
119121
onEndScroll();
120122
}
121123

122-
const onScroll = throttle(function () {
123-
updateFixedPositionClass();
124-
if (!disableOnScroll) {
125-
activateTopHeadingTocElement();
126-
}
127-
}, 50);
124+
const onScroll = throttle(
125+
function () {
126+
updateFixedPositionClass();
127+
if (!disableOnScroll) {
128+
activateTopHeadingTocElement();
129+
}
130+
},
131+
50,
132+
{ leading: true }
133+
);
128134

129135
const onEndScroll = debounce(function () {
130136
debug("scrolling ended");
@@ -141,6 +147,14 @@
141147
}
142148
}, 50);
143149

150+
const onResize = throttle(
151+
function () {
152+
updateFixedPositionClass();
153+
},
154+
50,
155+
{ leading: true }
156+
);
157+
144158
function onTocElementClick(event) {
145159
if (event.target.nodeName === "A") {
146160
const parentElement = event.target.parentElement;
@@ -153,15 +167,26 @@
153167
}
154168
}
155169

156-
function updateFixedPositionClass() {
157-
const top = getTop();
158-
if (fixedPositionTop === null) {
159-
fixedPositionTop = tocElement.offsetTop;
170+
function onToggleTocClick(event) {
171+
event.stopPropagation();
172+
const showing = document.body.classList.toggle("show-toc");
173+
if (showing) {
174+
document.documentElement.addEventListener("click", onToggleTocClick);
175+
} else {
176+
document.documentElement.removeEventListener("click", onToggleTocClick);
160177
}
161-
if (top > fixedPositionTop) {
162-
tocElement.classList.add("fixed-toc");
178+
}
179+
180+
function updateFixedPositionClass() {
181+
const computedStyle = window.getComputedStyle(document.documentElement);
182+
const bannerHeight = parseInt(
183+
computedStyle.getPropertyValue("--layout-banner-height"),
184+
10
185+
);
186+
if (getTop() >= bannerHeight) {
187+
document.body.classList.add("fixed-toc");
163188
} else {
164-
tocElement.classList.remove("fixed-toc");
189+
document.body.classList.remove("fixed-toc");
165190
}
166191
}
167192

@@ -224,7 +249,7 @@
224249
}
225250

226251
function isInViewport(element) {
227-
if(!element) {
252+
if (!element) {
228253
return false;
229254
}
230255
const rect = element.getBoundingClientRect();

src/main/ruby/lib/spring-asciidoctor-backends/body_template.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
</div>
77
</div>
88
</div>
9-
<div id="navbar-container" class="container" role="navigation">
10-
<div id="navbar" class="contained" role="navigation"></div>
9+
<div id="tocbar-container" class="container" role="navigation">
10+
<div id="tocbar" class="contained" role="navigation">
11+
<button id="toggle-toc"></button>
12+
</div>
1113
</div>
1214
<div id="main-container" class="container">
1315
<div id="main" class="contained">

0 commit comments

Comments
 (0)