Skip to content

Sidebar Mobile Support #252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 103 additions & 2 deletions assets/css/v2/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
--sidebar-line-box-left: 12px;
--sidebar-width: 22rem;
--sidebar-line-width: 11.5px;
--sidebar-mobile-top-displacement: 5rem;
--side-gutter-width: 20rem;
--table-top-bottom-spacing: 1rem;
--table-row-space-between: 1.5rem;
Expand Down Expand Up @@ -266,6 +267,10 @@ header {
padding: 20px 10px;
}

.nav-item-explore {
margin: 0;
}

.navbar-button {
padding: 0.5rem 0.5rem;
border: none;
Expand Down Expand Up @@ -462,6 +467,10 @@ nav {
position: relative;
z-index: 2;
min-height: 74vh;

.sidebar__mobile__toggle {
display: none;
}
}

.sidebar-layout::before {
Expand Down Expand Up @@ -525,8 +534,84 @@ nav {
column-gap: var(--grid-column-gutter);
}

.sidebar-layout {
display: none;
.content-layout .breadcrumb-layout {
position: sticky;
top: 0;
z-index: 3;
}

body:has(.sidebar__mobile-open) {
/* Disable scrolling in main content + hide footer if the sidebar is visible */
overflow-y: hidden;

.sidebar-layout {
position: absolute;
height: 100%;
}

footer {
display: none;
}

.sidebar-layout .sidebar__mobile__toggle {
display: flex;
align-items: center;
position: sticky;
top: 1rem;
margin-top: 2rem;
margin-left: 2rem;
margin-right: 2rem;
padding: 0.5rem;
color: white;
background-color: oklch(var(--color-brand));
}
}

.sidebar__mobile__toggle {
background-color: transparent;
border: none;

.lucide {
margin-right: 1rem;
}
}

.main-layout {
/* Mobile support for sidebar */
display: flex;
flex-direction: column;
position: relative;

.sidebar-layout {
min-height: fit-content;
background: white;
z-index: 999;
width: calc(100% + 4rem);
margin-left: -2rem;

&::before {
display: none;
}

nav {
width: 100%;
display: none;
top: var(--sidebar-mobile-top-displacement);
max-height: calc(100vh - var(--sidebar-mobile-top-displacement));
padding: 0 2rem;

.sidebar__container {
width: 100%;
}
}
}

.content-layout {
.breadcrumb-layout .sidebar__mobile__toggle {
display: inline;
padding: 0;
}
}
}

main {
Expand Down Expand Up @@ -933,6 +1018,10 @@ button:has(~ .product-selector[style*="none"]) > .product-selector-button-icon {
}
}

nav.sidebar.sidebar__mobile-open {
display: block;
}

/* MARK: Content
*/

Expand All @@ -941,6 +1030,18 @@ p {
line-height: 1.5rem;
}

.breadcrumb-layout {
position: relative;
background-color: white;
width: calc(100% + 4rem);
margin-left: -2rem;
padding: 1rem 2rem;

.sidebar__mobile__toggle {
display: none;
}
}

.breadcrumb {
color: var(--color-foreground);
text-decoration: none;
Expand Down
44 changes: 44 additions & 0 deletions assets/js/sidebar-v2.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
document.addEventListener('click', (e) => {
const toggle = e.target.closest('.sidebar__toggle');
const sidebarMobileToggle = e.target.closest('.sidebar__mobile__toggle');
if (toggle) {
const chevron = toggle.querySelector('.sidebar__chevron');
const expanded = toggle.getAttribute('aria-expanded') === 'true';
Expand All @@ -14,5 +15,48 @@ document.addEventListener('click', (e) => {
if (chevron) {
chevron.classList.toggle('sidebar__chevron--open', !expanded);
}
} else if (sidebarMobileToggle) {
// Show the sidebar
const sidebar = document.getElementById('sidebar-v2');
const expanded =
sidebarMobileToggle.getAttribute('aria-expanded') === 'true';

if (!expanded) {
sidebar.classList.add('sidebar__mobile-open');
} else {
sidebar.classList.remove('sidebar__mobile-open');
}

// Set the aria for all the toggle buttons so they are in lockstep
const toggleButtons = document.getElementsByClassName(
'sidebar__mobile__toggle'
);
for (const button of [...toggleButtons]) {
button.setAttribute('aria-expanded', String(!expanded));
}
}
});

const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback(...args);
}, wait);
};
};

window.addEventListener(
'resize',
debounce(() => {
const sidebar = document.getElementById('sidebar-v2');

if (
window.innerWidth > 88 * 16 &&
sidebar.classList.contains('sidebar__mobile-open')
) {
sidebar.classList.remove('sidebar__mobile-open');
}
}, 200)
);
5 changes: 3 additions & 2 deletions layouts/_default/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,15 @@

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

<section id="maincontent" class="content-layout">
<div data-cms-edit="content" class="text-content">
<section class="breadcrumb-layout" data-mf="true" style="display: none;">
<section class="breadcrumb-layout wide" data-mf="true" style="display: none;">
{{ if not .IsHome }}
{{ if not (in .Params.display_breadcrumb "false" ) }}
{{ partial "breadcrumb" .}}
Expand Down
3 changes: 2 additions & 1 deletion layouts/_default/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
<main class="content col d-block align-top content-has-toc" role="main" data-mf="true" style="display: none">
<section class="main-layout">
<div class="sidebar-layout" id="sidebar-layout">
<button class="sidebar__mobile__toggle" aria-expanded="false" data-mf="true">{{ partial "lucide" (dict "context" . "icon" "x")}}Close</button>
<nav data-mf="true" id="sidebar-v2" class="sidebar" style="display:none;">
{{ partial "sidebar-v2.html" . }}
</nav>
</div>

<section id="maincontent" class="content-layout" data-mf="true" style="display: none">
<div data-cms-edit="content" class="text-content list-page">
<section class="breadcrumb-layout">
<section class="breadcrumb-layout wide">
{{ if not .IsHome }}
{{ if not (in .Params.display_breadcrumb "false" ) }}
{{ partial "breadcrumb" .}}
Expand Down
1 change: 1 addition & 0 deletions layouts/partials/breadcrumb.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<nav aria-label="breadcrumb" class="breadcrumb navbar">
<div class="nav flex-md-row">
<ol class="breadcrumb">
<button class="sidebar__mobile__toggle" aria-expanded="false" data-mf="true">{{ partial "lucide" (dict "context" . "icon" "align-justify") }}</button>
<li><a href="/" alt="NGINX Docs Home">Home</a></li>
{{- define "breadcrumb" -}}
{{- with .Parent -}}
Expand Down
Loading