Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d1a018c

Browse files
committedMar 1, 2022
doc: make header smaller and dropdown click-driven when JS is on
1 parent b3723fa commit d1a018c

File tree

4 files changed

+128
-41
lines changed

4 files changed

+128
-41
lines changed
 

‎doc/api_assets/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# API Reference Document Assets
22

3+
## api.js
4+
5+
The main script for API reference documents.
6+
37
## hljs.css
48

59
The syntax theme for code snippets in API reference documents.

‎doc/api_assets/api.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
'use strict';
2+
3+
// Check if we have Javascript support
4+
document.querySelector(':root').classList.add('has-js');
5+
6+
// Restore user mode preferences
7+
const kCustomPreference = 'customDarkTheme';
8+
const userSettings = sessionStorage.getItem(kCustomPreference);
9+
const themeToggleButton = document.getElementById('theme-toggle-btn');
10+
if (userSettings === null && window.matchMedia) {
11+
const mq = window.matchMedia('(prefers-color-scheme: dark)');
12+
if ('onchange' in mq) {
13+
function mqChangeListener(e) {
14+
document.documentElement.classList.toggle('dark-mode', e.matches);
15+
}
16+
mq.addEventListener('change', mqChangeListener);
17+
if (themeToggleButton) {
18+
themeToggleButton.addEventListener('click', function() {
19+
mq.removeEventListener('change', mqChangeListener);
20+
}, { once: true });
21+
}
22+
}
23+
if (mq.matches) {
24+
document.documentElement.classList.add('dark-mode');
25+
}
26+
} else if (userSettings === 'true') {
27+
document.documentElement.classList.add('dark-mode');
28+
}
29+
if (themeToggleButton) {
30+
themeToggleButton.hidden = false;
31+
themeToggleButton.addEventListener('click', function() {
32+
sessionStorage.setItem(
33+
kCustomPreference,
34+
document.documentElement.classList.toggle('dark-mode')
35+
);
36+
});
37+
}
38+
39+
// Handle pickers with click/taps rather than hovers
40+
const pickers = document.querySelectorAll('.picker-header');
41+
for(const picker of pickers) {
42+
picker.addEventListener('click', e => {
43+
if (!e.target.closest('.picker')) {
44+
e.preventDefault();
45+
}
46+
47+
if (picker.classList.contains('expanded')) {
48+
picker.classList.remove('expanded');
49+
} else {
50+
for (const other of pickers) {
51+
other.classList.remove('expanded');
52+
}
53+
54+
picker.classList.add('expanded');
55+
}
56+
});
57+
}
58+
59+
// Track when the header is in sticky position
60+
const header = document.querySelector(".header");
61+
let ignoreNextIntersection = false;
62+
new IntersectionObserver(
63+
([e]) => {
64+
const currentStatus = header.classList.contains('is-pinned');
65+
const newStatus = e.intersectionRatio < 1;
66+
67+
// Same status, do nothing
68+
if(currentStatus === newStatus) {
69+
return;
70+
} else if(ignoreNextIntersection) {
71+
ignoreNextIntersection = false;
72+
return;
73+
}
74+
75+
/*
76+
To avoid flickering, ignore the next change event that is triggered
77+
as the visible elements in the header change once we pin it.
78+
79+
The timer is reset anyway after few milliseconds
80+
*/
81+
ignoreNextIntersection = true;
82+
setTimeout(() => ignoreNextIntersection = false, 50);
83+
84+
header.classList.toggle('is-pinned', newStatus);
85+
},
86+
{ threshold: [1] }
87+
).observe(header);

‎doc/api_assets/style.css

+35-5
Original file line numberDiff line numberDiff line change
@@ -189,19 +189,23 @@ li.picker-header .expanded-arrow {
189189
display: none;
190190
}
191191

192-
li.picker-header:hover .collapsed-arrow {
192+
li.picker-header.expanded .collapsed-arrow,
193+
:root:not(.has-js) li.picker-header:hover .collapsed-arrow {
193194
display: none;
194195
}
195196

196-
li.picker-header:hover .expanded-arrow {
197+
li.picker-header.expanded .expanded-arrow,
198+
:root:not(.has-js) li.picker-header:hover .expanded-arrow {
197199
display: inline-block;
198200
}
199201

200-
li.picker-header:hover > a {
202+
li.picker-header.expanded > a,
203+
:root:not(.has-js) li.picker-header:hover > a {
201204
border-radius: 2px 2px 0 0;
202205
}
203206

204-
li.picker-header:hover > .picker {
207+
li.picker-header.expanded > .picker,
208+
:root:not(.has-js) li.picker-header:hover > .picker {
205209
display: block;
206210
z-index: 1;
207211
}
@@ -807,13 +811,31 @@ kbd {
807811
background-color: var(--color-fill-app);
808812
}
809813

810-
@media not screen, (max-height: 1000px) {
814+
@media not screen, (max-width: 600px), (max-height: 1000px) {
811815
.header {
812816
position: relative;
813817
top: 0;
814818
}
815819
}
816820

821+
.header .pinned-header {
822+
display: none;
823+
margin-right: 0.4rem;
824+
font-weight: 700;
825+
}
826+
827+
.header.is-pinned .header-container {
828+
display: none;
829+
}
830+
831+
.header.is-pinned .pinned-header {
832+
display: inline;
833+
}
834+
835+
.header.is-pinned #gtoc {
836+
margin: 0;
837+
}
838+
817839
.header-container {
818840
display: flex;
819841
align-items: center;
@@ -845,6 +867,14 @@ kbd {
845867
padding-right: 0;
846868
}
847869

870+
.header #gtoc > ul > li.pinned-header {
871+
display: none;
872+
}
873+
874+
.header.is-pinned #gtoc > ul > li.pinned-header {
875+
display: inline;
876+
}
877+
848878
#gtoc > ul > li.gtoc-picker-header {
849879
display: none;
850880
}

‎doc/template.html

+2-36
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ <h1>Node.js __VERSION__ documentation</h1>
3939
</div>
4040
<div id="gtoc">
4141
<ul>
42+
<li class="pinned-header">Node.js __VERSION__</li>
4243
__TOC_PICKER__
4344
__GTOC_PICKER__
4445
__ALTDOCS__
@@ -73,41 +74,6 @@ <h1>Node.js __VERSION__ documentation</h1>
7374
</div>
7475
</div>
7576
</div>
76-
<script>
77-
'use strict';
78-
{
79-
const kCustomPreference = 'customDarkTheme';
80-
const userSettings = sessionStorage.getItem(kCustomPreference);
81-
const themeToggleButton = document.getElementById('theme-toggle-btn');
82-
if (userSettings === null && window.matchMedia) {
83-
const mq = window.matchMedia('(prefers-color-scheme: dark)');
84-
if ('onchange' in mq) {
85-
function mqChangeListener(e) {
86-
document.documentElement.classList.toggle('dark-mode', e.matches);
87-
}
88-
mq.addEventListener('change', mqChangeListener);
89-
if (themeToggleButton) {
90-
themeToggleButton.addEventListener('click', function() {
91-
mq.removeEventListener('change', mqChangeListener);
92-
}, { once: true });
93-
}
94-
}
95-
if (mq.matches) {
96-
document.documentElement.classList.add('dark-mode');
97-
}
98-
} else if (userSettings === 'true') {
99-
document.documentElement.classList.add('dark-mode');
100-
}
101-
if (themeToggleButton) {
102-
themeToggleButton.hidden = false;
103-
themeToggleButton.addEventListener('click', function() {
104-
sessionStorage.setItem(
105-
kCustomPreference,
106-
document.documentElement.classList.toggle('dark-mode')
107-
);
108-
});
109-
}
110-
}
111-
</script>
77+
<script src="assets/api.js" type="text/javascript"></script>
11278
</body>
11379
</html>

0 commit comments

Comments
 (0)
Please sign in to comment.