Skip to content

Commit 309d137

Browse files
committed
Mobile menu
1 parent 367f07d commit 309d137

File tree

5 files changed

+119
-38
lines changed

5 files changed

+119
-38
lines changed

website/build.mjs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ function buildMenus(html) {
160160
const headings = getHeadingList().filter(({ level }) => level > 1);
161161
let result = '<div class="wrapper">';
162162
if (isBlog) {
163-
result += `<div class="docs-menu sticky">${ blogMenuCache }</div>`;
163+
result += `<div class="docs-menu sticky"><div class="mobile-trigger"></div>${ blogMenuCache }</div>`;
164164
} else if (isDocs) {
165-
result += `<div class="docs-menu sticky">${ docsMenu }</div>`;
165+
result += `<div class="docs-menu sticky"><div class="mobile-trigger"></div>${ docsMenu }</div>`;
166166
}
167167
result += `<div class="content">${ html }</div>`;
168168
if (headings.length && !Object.hasOwn(fileMetadata, 'disableContentMenu')) {
@@ -274,8 +274,6 @@ async function buildPlayground(template, version, versions) {
274274
const versionsMenu = await buildPlaygroundMenuForVersion(versions, version);
275275
let playground = template.replace('{content}', `${ playgroundContent }`);
276276
playground = playground.replace('{base}', `${ BASE }`);
277-
playground = playground.replace('{blog-menu}', '');
278-
playground = playground.replace('{docs-menu}', '');
279277
playground = playground.replace('{title}', 'Playground - ');
280278
playground = playground.replace('{base}', `${ BASE }`);
281279
playground = playground.replace('{core-js-bundle}', `${ bundleScript }`);
@@ -325,7 +323,7 @@ let isChangelog;
325323

326324
async function build() {
327325
const template = await readFile(TEMPLATE_PATH);
328-
const blogMenuHtml = await buildBlogMenu();
326+
await buildBlogMenu();
329327
const mdFiles = await getAllMdFiles(DOCS_DIR);
330328
const versions = await getVersionsFromMdFiles(mdFiles);
331329
const uniqueVersions = [...new Set(versions)];
@@ -345,15 +343,11 @@ async function build() {
345343
const match = /^# (?<title>.+)$/m.exec(content);
346344
const title = match && match.groups && match.groups.title ? `${ match.groups.title } - ` : '';
347345

348-
let mobileDocsMenu = '';
349-
let mobileBlogMenu = '';
350346
if (currentVersion !== versions[i]) {
351347
currentVersion = versions[i];
352348
docsMenu = await buildDocsMenuForVersion(currentVersion);
353349
versionsMenu = await buildVersionsMenu(uniqueVersions, currentVersion);
354350
}
355-
if (isDocs) mobileDocsMenu = docsMenu;
356-
if (isBlog) mobileBlogMenu = blogMenuHtml;
357351

358352
htmlFileName = mdPath.replace(DOCS_DIR, '').replace(/\.md$/i, '.html');
359353
const htmlFilePath = path.join(RESULT_DIR, htmlFileName);
@@ -362,8 +356,6 @@ async function build() {
362356
let resultHtml = template.replace('{content}', `${ htmlContent.replaceAll('$', '&#36;') }`);
363357

364358
resultHtml = resultHtml.replace('{title}', title);
365-
resultHtml = resultHtml.replace('{docs-menu}', `${ mobileDocsMenu }`);
366-
resultHtml = resultHtml.replace('{blog-menu}', `${ mobileBlogMenu }`);
367359
resultHtml = resultHtml.replace('{base}', `${ BASE }`);
368360
resultHtml = resultHtml.replace('{core-js-bundle}', `${ bundleScript }`);
369361
resultHtml = resultHtml.replace('{core-js-bundle-esmodules}', `${ bundleESModulesScript }`);

website/src/index.html

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,8 @@
3232
</div>
3333
<div class="menu">
3434
<div class="menu-items">
35-
<div class="menu-item">
36-
<a href="./blog/" tabindex="1">Blog</a>
37-
<div class="mobile-docs-menu">{blog-menu}</div>
38-
</div>
39-
<div class="menu-item">
40-
<a href="./docs/" tabindex="3">Docs</a>
41-
<div class="mobile-docs-menu">{docs-menu}</div>
42-
</div>
35+
<div class="menu-item"><a href="./blog/" tabindex="1">Blog</a></div>
36+
<div class="menu-item"><a href="./docs/" tabindex="3">Docs</a></div>
4337
<div class="menu-item"><a href="./playground" tabindex="2">Playground</a></div>
4438
<div class="menu-item"><a href="./changelog" tabindex="4">Changelog</a></div>
4539
<div class="socials">

website/src/js/main.js

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ hljs.registerLanguage('json', json);
1313
hljs.registerLanguage('sh', bash);
1414

1515
let initialized = false;
16+
// eslint-disable-next-line max-statements -- a lot of browser logic here
1617
function init() {
1718
if (initialized) return;
1819
initialized = true;
1920
const CONTENT_MENU_TOP = 150;
21+
const SECTION_MENU_TOP = 150;
2022
const menuSwitcher = document.getElementById('menu-switcher');
2123
const menuBackdrop = document.querySelector('.menu > .backdrop');
2224
const [menu] = document.getElementsByClassName('menu');
@@ -30,9 +32,10 @@ function init() {
3032
const docsVersionLinks = document.querySelectorAll('.with-docs-version');
3133
const docsMenuItems = document.querySelectorAll('.docs-menu li > a');
3234
const docsCollapsibleMenuItems = document.querySelectorAll('.docs-menu > ul > li.collapsible');
33-
const mobileDocsMenuItems = document.querySelectorAll('.mobile-docs-menu li > a');
3435
const contentMenu = document.querySelector('.table-of-contents');
3536
const contentMenuTrigger = document.querySelector('.table-of-contents .mobile-trigger');
37+
const sectionMenu = document.querySelector('.docs-menu');
38+
const sectionMenuTrigger = document.querySelector('.docs-menu .mobile-trigger');
3639
let isDocs, docsVersion;
3740
const currentPath = getRelativePath();
3841

@@ -153,24 +156,17 @@ function init() {
153156
}
154157
}
155158

156-
let mobileFound = false;
157-
for (const link of mobileDocsMenuItems) {
158-
const href = link.getAttribute('href');
159-
if (href && href === currentPath) {
160-
setActiveDocsMenuItem(link);
161-
mobileFound = true;
162-
break;
163-
}
164-
}
165-
166159
!found && setActiveDocsMenuItem(docsMenuItems[0]);
167-
!mobileFound && setActiveDocsMenuItem(mobileDocsMenuItems[0]);
168160
}
169161

170162
function fixContentMenuPosition(scroll) {
171163
contentMenu.style.top = scroll <= CONTENT_MENU_TOP ? `${ CONTENT_MENU_TOP - scroll }px` : 'unset';
172164
}
173165

166+
function fixSectionMenuPosition(scroll) {
167+
sectionMenu.style.top = scroll <= SECTION_MENU_TOP ? `${ SECTION_MENU_TOP - scroll }px` : 'unset';
168+
}
169+
174170
function openFirstCollapsibleMenuItem() {
175171
if (!isDocsPage()) return;
176172
docsCollapsibleMenuItems[0].classList.add('active');
@@ -179,6 +175,7 @@ function init() {
179175
function processStickyBlocks() {
180176
if (stickyBlocks) {
181177
const contentMenuPosition = contentMenu && globalThis.getComputedStyle(contentMenu).position;
178+
const sectionMenuPosition = sectionMenu && globalThis.getComputedStyle(sectionMenu).position;
182179
let stuck = window.pageYOffset > 150;
183180
if (stuck) addStuck();
184181
window.addEventListener('scroll', () => {
@@ -194,6 +191,9 @@ function init() {
194191
if (contentMenuPosition === 'fixed') {
195192
fixContentMenuPosition(yScroll);
196193
}
194+
if (sectionMenuPosition === 'fixed') {
195+
fixSectionMenuPosition(yScroll);
196+
}
197197
});
198198
}
199199
}
@@ -209,6 +209,17 @@ function init() {
209209
contentMenuTrigger && contentMenuTrigger.addEventListener('click', e => {
210210
e.preventDefault();
211211
contentMenu.classList.toggle('active');
212+
if (contentMenu.classList.contains('active') && sectionMenu && sectionMenu.classList.contains('active')) {
213+
sectionMenu.classList.remove('active');
214+
}
215+
});
216+
217+
sectionMenuTrigger && sectionMenuTrigger.addEventListener('click', e => {
218+
e.preventDefault();
219+
sectionMenu.classList.toggle('active');
220+
if (sectionMenu.classList.contains('active') && contentMenu && contentMenu.classList.contains('active')) {
221+
contentMenu.classList.remove('active');
222+
}
212223
});
213224

214225
hljs.addPlugin(new RunButtonPlugin());

website/src/scss/parts/header.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ nav {
158158
position: absolute;
159159
top: 25px;
160160
right: 15px;
161-
z-index: 3;
161+
z-index: 6;
162162

163163
a {
164164
display: block;

website/src/scss/parts/main.scss

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ main {
8484
flex-shrink: 0;
8585
line-height: 1.3;
8686

87-
88-
height: calc(100vh - 170px);
87+
height: calc(100vh - 150px);
88+
height: calc(100dvh - 150px);
8989
overflow-y: auto;
9090
scrollbar-width: none;
9191
@include themify($themes) {
@@ -94,10 +94,87 @@ main {
9494

9595
&.stuck {
9696
height: calc(100vh - 2rem);
97+
height: calc(100dvh - 2rem);
9798
}
9899

99-
@include media('max', 'lg') {
100-
display: none;
100+
@include media('max', 'xl') {
101+
position: fixed;
102+
left: 1rem;
103+
bottom: 0;
104+
top: auto;
105+
min-width: 1.75rem;
106+
z-index: 3;
107+
@include themify($themes) {
108+
background-color: themed('background-light');
109+
box-shadow: 5px 5px 7px -6px themed('background-highlight');
110+
border-right: 0;
111+
}
112+
113+
.mobile-trigger {
114+
position: absolute;
115+
display: flex;
116+
top: 0;
117+
bottom: 0;
118+
width: 1.75rem;
119+
cursor: pointer;
120+
align-items: center;
121+
justify-content: center;
122+
right: 0;
123+
124+
&:after {
125+
content: '';
126+
display: block;
127+
width: 10px;
128+
height: 10px;
129+
transform: rotate(-45deg);
130+
margin-left: -2px;
131+
@include themify($themes) {
132+
border-right: 2px solid themed('link-color');
133+
border-bottom: 2px solid themed('link-color');
134+
}
135+
}
136+
&:hover {
137+
&:after {
138+
@include themify($themes) {
139+
border-right: 2px solid themed('link-color-hover');
140+
border-bottom: 2px solid themed('link-color-hover');
141+
}
142+
}
143+
}
144+
}
145+
146+
li {
147+
@include media('max', 'xl') {
148+
display: none;
149+
}
150+
}
151+
152+
&.active {
153+
min-width: 180px;
154+
max-width: 270px;
155+
padding-left: 1rem;
156+
157+
li {
158+
display: block;
159+
}
160+
161+
.mobile-trigger {
162+
&:after {
163+
transform: rotate(135deg);
164+
margin-left: 5px;
165+
}
166+
}
167+
}
168+
169+
&.stuck {
170+
height: 100vh;
171+
height: 100dvh;
172+
padding-top: 1rem;
173+
}
174+
}
175+
176+
@include media('max', 'sm') {
177+
left: 0;
101178
}
102179

103180
a {
@@ -152,9 +229,13 @@ main {
152229

153230
.content {
154231
width: 100%;
155-
padding: 0 1rem;
232+
padding: 1rem 1rem 0;
156233
min-width: 0;
157234
text-align: justify;
235+
236+
@include media("min", "md") {
237+
padding: 0 1rem;
238+
}
158239
}
159240

160241
.table-of-contents {
@@ -165,12 +246,14 @@ main {
165246
max-width: 20%;
166247
min-width: 20%;
167248
height: calc(100vh - 150px);
249+
height: calc(100dvh - 150px);
168250
overflow-y: auto;
169251
scrollbar-width: none;
170252
-ms-overflow-style: none;
171253

172254
&.stuck {
173255
height: calc(100vh - 2rem);
256+
height: calc(100dvh - 2rem);
174257
}
175258

176259
.mobile-trigger {
@@ -238,7 +321,8 @@ main {
238321
}
239322

240323
&.stuck {
241-
height: calc(100vh);
324+
height: 100vh;
325+
height: 100dvh;
242326
padding-top: 1rem;
243327
}
244328
}

0 commit comments

Comments
 (0)