Skip to content

Commit 9c28d1c

Browse files
authored
Sidebar: Mobile support (#252)
1 parent 698ddfd commit 9c28d1c

File tree

5 files changed

+153
-5
lines changed

5 files changed

+153
-5
lines changed

assets/css/v2/style.css

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
--sidebar-line-box-left: 12px;
9494
--sidebar-width: 22rem;
9595
--sidebar-line-width: 11.5px;
96+
--sidebar-mobile-top-displacement: 5rem;
9697
--side-gutter-width: 20rem;
9798
--table-top-bottom-spacing: 1rem;
9899
--table-row-space-between: 1.5rem;
@@ -268,6 +269,10 @@ header {
268269
padding: 20px 10px;
269270
}
270271

272+
.nav-item-explore {
273+
margin: 0;
274+
}
275+
271276
.navbar-button {
272277
padding: 0.5rem 0.5rem;
273278
border: none;
@@ -464,6 +469,10 @@ nav {
464469
position: relative;
465470
z-index: 2;
466471
min-height: 74vh;
472+
473+
.sidebar__mobile__toggle {
474+
display: none;
475+
}
467476
}
468477

469478
.sidebar-layout::before {
@@ -527,8 +536,84 @@ nav {
527536
column-gap: var(--grid-column-gutter);
528537
}
529538

530-
.sidebar-layout {
531-
display: none;
539+
.content-layout .breadcrumb-layout {
540+
position: sticky;
541+
top: 0;
542+
z-index: 3;
543+
}
544+
545+
body:has(.sidebar__mobile-open) {
546+
/* Disable scrolling in main content + hide footer if the sidebar is visible */
547+
overflow-y: hidden;
548+
549+
.sidebar-layout {
550+
position: absolute;
551+
height: 100%;
552+
}
553+
554+
footer {
555+
display: none;
556+
}
557+
558+
.sidebar-layout .sidebar__mobile__toggle {
559+
display: flex;
560+
align-items: center;
561+
position: sticky;
562+
top: 1rem;
563+
margin-top: 2rem;
564+
margin-left: 2rem;
565+
margin-right: 2rem;
566+
padding: 0.5rem;
567+
color: white;
568+
background-color: oklch(var(--color-brand));
569+
}
570+
}
571+
572+
.sidebar__mobile__toggle {
573+
background-color: transparent;
574+
border: none;
575+
576+
.lucide {
577+
margin-right: 1rem;
578+
}
579+
}
580+
581+
.main-layout {
582+
/* Mobile support for sidebar */
583+
display: flex;
584+
flex-direction: column;
585+
position: relative;
586+
587+
.sidebar-layout {
588+
min-height: fit-content;
589+
background: white;
590+
z-index: 999;
591+
width: calc(100% + 4rem);
592+
margin-left: -2rem;
593+
594+
&::before {
595+
display: none;
596+
}
597+
598+
nav {
599+
width: 100%;
600+
display: none;
601+
top: var(--sidebar-mobile-top-displacement);
602+
max-height: calc(100vh - var(--sidebar-mobile-top-displacement));
603+
padding: 0 2rem;
604+
605+
.sidebar__container {
606+
width: 100%;
607+
}
608+
}
609+
}
610+
611+
.content-layout {
612+
.breadcrumb-layout .sidebar__mobile__toggle {
613+
display: inline;
614+
padding: 0;
615+
}
616+
}
532617
}
533618

534619
main {
@@ -773,6 +858,10 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon {
773858
/* MARK: Sidebar
774859
*/
775860

861+
nav.sidebar.sidebar__mobile-open {
862+
display: block;
863+
}
864+
776865
.sidebar {
777866
--color-foreground: oklch(0 0 0 / 0.75);
778867

@@ -963,6 +1052,18 @@ p {
9631052
line-height: 1.5rem;
9641053
}
9651054

1055+
.breadcrumb-layout {
1056+
position: relative;
1057+
background-color: white;
1058+
width: calc(100% + 4rem);
1059+
margin-left: -2rem;
1060+
padding: 1rem 2rem;
1061+
1062+
.sidebar__mobile__toggle {
1063+
display: none;
1064+
}
1065+
}
1066+
9661067
.breadcrumb {
9671068
color: oklch(var(--color-foreground));
9681069
text-decoration: none;

assets/js/sidebar-v2.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
document.addEventListener('click', (e) => {
22
const toggle = e.target.closest('.sidebar__toggle');
3+
const sidebarMobileToggle = e.target.closest('.sidebar__mobile__toggle');
34
if (toggle) {
45
const chevron = toggle.querySelector('.sidebar__chevron');
56
const expanded = toggle.getAttribute('aria-expanded') === 'true';
@@ -14,5 +15,48 @@ document.addEventListener('click', (e) => {
1415
if (chevron) {
1516
chevron.classList.toggle('sidebar__chevron--open', !expanded);
1617
}
18+
} else if (sidebarMobileToggle) {
19+
// Show the sidebar
20+
const sidebar = document.getElementById('sidebar-v2');
21+
const expanded =
22+
sidebarMobileToggle.getAttribute('aria-expanded') === 'true';
23+
24+
if (!expanded) {
25+
sidebar.classList.add('sidebar__mobile-open');
26+
} else {
27+
sidebar.classList.remove('sidebar__mobile-open');
28+
}
29+
30+
// Set the aria for all the toggle buttons so they are in lockstep
31+
const toggleButtons = document.getElementsByClassName(
32+
'sidebar__mobile__toggle'
33+
);
34+
for (const button of [...toggleButtons]) {
35+
button.setAttribute('aria-expanded', String(!expanded));
36+
}
1737
}
1838
});
39+
40+
const debounce = (callback, wait) => {
41+
let timeoutId = null;
42+
return (...args) => {
43+
window.clearTimeout(timeoutId);
44+
timeoutId = window.setTimeout(() => {
45+
callback(...args);
46+
}, wait);
47+
};
48+
};
49+
50+
window.addEventListener(
51+
'resize',
52+
debounce(() => {
53+
const sidebar = document.getElementById('sidebar-v2');
54+
55+
if (
56+
window.innerWidth > 88 * 16 &&
57+
sidebar.classList.contains('sidebar__mobile-open')
58+
) {
59+
sidebar.classList.remove('sidebar__mobile-open');
60+
}
61+
}, 200)
62+
);

layouts/_default/docs.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,15 @@
6969

7070
<section class="main-layout">
7171
<div class="sidebar-layout" id="sidebar-layout">
72-
<nav data-mf="true" id="sidebar-v2" class="sidebar" style="display:none;">
72+
<button class="sidebar__mobile__toggle" aria-expanded="false" data-mf="true">{{ partial "lucide" (dict "context" . "icon" "x")}}Close</button>
73+
<nav data-mf="true" id="sidebar-v2" class="sidebar">
7374
{{ partial "sidebar-v2.html" . }}
7475
</nav>
7576
</div>
7677

7778
<section id="maincontent" class="content-layout">
7879
<div data-cms-edit="content" class="text-content">
79-
<section class="breadcrumb-layout" data-mf="true" style="display: none;">
80+
<section class="breadcrumb-layout wide" data-mf="true" style="display: none;">
8081
{{ if not .IsHome }}
8182
{{ if not (in .Params.display_breadcrumb "false" ) }}
8283
{{ partial "breadcrumb" .}}

layouts/_default/list.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@
1313
<main class="content col d-block align-top content-has-toc" role="main" data-mf="true" style="display: none">
1414
<section class="main-layout">
1515
<div class="sidebar-layout" id="sidebar-layout">
16+
<button class="sidebar__mobile__toggle" aria-expanded="false" data-mf="true">{{ partial "lucide" (dict "context" . "icon" "x")}}Close</button>
1617
<nav data-mf="true" id="sidebar-v2" class="sidebar" style="display:none;">
1718
{{ partial "sidebar-v2.html" . }}
1819
</nav>
1920
</div>
2021

2122
<section id="maincontent" class="content-layout" data-mf="true" style="display: none">
2223
<div data-cms-edit="content" class="text-content list-page">
23-
<section class="breadcrumb-layout">
24+
<section class="breadcrumb-layout wide">
2425
{{ if not .IsHome }}
2526
{{ if not (in .Params.display_breadcrumb "false" ) }}
2627
{{ partial "breadcrumb" .}}

layouts/partials/breadcrumb.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<nav aria-label="breadcrumb" class="breadcrumb navbar">
22
<div class="nav flex-md-row">
33
<ol class="breadcrumb">
4+
<button class="sidebar__mobile__toggle" aria-expanded="false" data-mf="true">{{ partial "lucide" (dict "context" . "icon" "align-justify") }}</button>
45
<li><a href="/" alt="NGINX Docs Home">Home</a></li>
56
{{- define "breadcrumb" -}}
67
{{- with .Parent -}}

0 commit comments

Comments
 (0)