Skip to content

Commit fec72f0

Browse files
committed
Mobile menu
1 parent 367f07d commit fec72f0

File tree

4 files changed

+111
-36
lines changed

4 files changed

+111
-36
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/main.scss

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

87-
88-
height: calc(100vh - 170px);
87+
height: calc(100vh - 150px);
8988
overflow-y: auto;
9089
scrollbar-width: none;
9190
@include themify($themes) {
@@ -96,8 +95,83 @@ main {
9695
height: calc(100vh - 2rem);
9796
}
9897

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

103177
a {
@@ -152,9 +226,13 @@ main {
152226

153227
.content {
154228
width: 100%;
155-
padding: 0 1rem;
229+
padding: 1rem 1rem 0;
156230
min-width: 0;
157231
text-align: justify;
232+
233+
@include media("min", "md") {
234+
padding: 0 1rem;
235+
}
158236
}
159237

160238
.table-of-contents {

0 commit comments

Comments
 (0)