UX: Make Sidebar more consistent with user menu on mobile (#17940)
Before this commit, we carried custom code and styles for the sidebar on mobile. This meant the look and feel of bringing up the sidebar on mobile was very different from the user menu resulting in a very inconsistent experience on mobile. Also, we could not leverage on the existing swipe to close support on mobile. In this commit, we made it such that the sidebar dropdown is always rendered on mobile and made the interaction with the dropdown more consistent with the user menu. There is also more parity with the old hamburger dropdown when the experimental sidebar is disabled.
This commit is contained in:
parent
e4de738f59
commit
7a05a9d411
|
@ -0,0 +1,12 @@
|
||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
|
||||||
|
export default class SidebarHamburgerDropdown extends Component {
|
||||||
|
@service appEvents;
|
||||||
|
|
||||||
|
@action
|
||||||
|
triggerRenderedAppEvent() {
|
||||||
|
this.appEvents.trigger("sidebar-hamburger-dropdown:rendered");
|
||||||
|
}
|
||||||
|
}
|
|
@ -225,6 +225,17 @@ const SiteHeaderComponent = MountWidget.extend(
|
||||||
this.appEvents.on("user-menu:rendered", this, "_animateMenu");
|
this.appEvents.on("user-menu:rendered", this, "_animateMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.siteSettings.enable_experimental_sidebar_hamburger &&
|
||||||
|
!this.sidebarEnabled
|
||||||
|
) {
|
||||||
|
this.appEvents.on(
|
||||||
|
"sidebar-hamburger-dropdown:rendered",
|
||||||
|
this,
|
||||||
|
"_animateMenu"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.dispatch("notifications:changed", "user-notifications");
|
this.dispatch("notifications:changed", "user-notifications");
|
||||||
this.dispatch("header:keyboard-trigger", "header");
|
this.dispatch("header:keyboard-trigger", "header");
|
||||||
this.dispatch("user-menu:navigation", "user-menu");
|
this.dispatch("user-menu:navigation", "user-menu");
|
||||||
|
@ -341,6 +352,17 @@ const SiteHeaderComponent = MountWidget.extend(
|
||||||
this.appEvents.off("user-menu:rendered", this, "_animateMenu");
|
this.appEvents.off("user-menu:rendered", this, "_animateMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.siteSettings.enable_experimental_sidebar_hamburger &&
|
||||||
|
!this.sidebarEnabled
|
||||||
|
) {
|
||||||
|
this.appEvents.off(
|
||||||
|
"sidebar-hamburger-dropdown:rendered",
|
||||||
|
this,
|
||||||
|
"_animateMenu"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.currentUser) {
|
if (this.currentUser) {
|
||||||
this.currentUser.off("status-changed", this, "queueRerender");
|
this.currentUser.off("status-changed", this, "queueRerender");
|
||||||
}
|
}
|
||||||
|
@ -373,6 +395,7 @@ const SiteHeaderComponent = MountWidget.extend(
|
||||||
|
|
||||||
_animateMenu() {
|
_animateMenu() {
|
||||||
const menuPanels = document.querySelectorAll(".menu-panel");
|
const menuPanels = document.querySelectorAll(".menu-panel");
|
||||||
|
|
||||||
if (menuPanels.length === 0) {
|
if (menuPanels.length === 0) {
|
||||||
if (this.site.mobileView) {
|
if (this.site.mobileView) {
|
||||||
this._animate = true;
|
this._animate = true;
|
||||||
|
|
|
@ -74,6 +74,11 @@ export default Controller.extend({
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always return dropdown on mobile
|
||||||
|
if (this.site.mobileView) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return enableSidebar;
|
return enableSidebar;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="hamburger-panel">
|
<div class="hamburger-panel">
|
||||||
<div class="hamburger-menu revamped menu-panel drop-down" data-max-width="320">
|
<div class="revamped menu-panel drop-down" data-max-width="320" {{did-insert this.triggerRenderedAppEvent}}>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="panel-body-content">
|
<div class="panel-body-contents">
|
||||||
<div class="sidebar-hamburger-dropdown">
|
<div class="sidebar-hamburger-dropdown">
|
||||||
<Sidebar::Sections @collapsableSections={{false}}/>
|
<Sidebar::Sections @collapsableSections={{false}}/>
|
||||||
<Sidebar::Footer @tagName="" />
|
<Sidebar::Footer @tagName="" />
|
||||||
|
|
|
@ -589,7 +589,7 @@ export default createWidget("header", {
|
||||||
toggleHamburger() {
|
toggleHamburger() {
|
||||||
if (
|
if (
|
||||||
this.siteSettings.enable_experimental_sidebar_hamburger &&
|
this.siteSettings.enable_experimental_sidebar_hamburger &&
|
||||||
(this.attrs.sidebarEnabled || this.site.mobileView)
|
this.attrs.sidebarEnabled
|
||||||
) {
|
) {
|
||||||
this.sendWidgetAction("toggleSidebar");
|
this.sendWidgetAction("toggleSidebar");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,7 +18,10 @@ acceptance("Sidebar - Mobile - User with sidebar enabled", function (needs) {
|
||||||
test("hidden by default", async function (assert) {
|
test("hidden by default", async function (assert) {
|
||||||
await visit("/");
|
await visit("/");
|
||||||
|
|
||||||
assert.ok(!exists(".sidebar-container"), "sidebar is not displayed");
|
assert.ok(
|
||||||
|
!exists(".sidebar-hamburger-dropdown"),
|
||||||
|
"sidebar is not displayed"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("clicking outside sidebar collapses it", async function (assert) {
|
test("clicking outside sidebar collapses it", async function (assert) {
|
||||||
|
@ -26,11 +29,11 @@ acceptance("Sidebar - Mobile - User with sidebar enabled", function (needs) {
|
||||||
|
|
||||||
await click(".hamburger-dropdown");
|
await click(".hamburger-dropdown");
|
||||||
|
|
||||||
assert.ok(exists(".sidebar-container"), "sidebar is displayed");
|
assert.ok(exists(".sidebar-hamburger-dropdown"), "sidebar is displayed");
|
||||||
|
|
||||||
await click("#main-outlet");
|
await click("#main-outlet");
|
||||||
|
|
||||||
assert.ok(!exists(".sidebar-container"), "sidebar is collapsed");
|
assert.ok(!exists(".sidebar-hamburger-dropdown"), "sidebar is collapsed");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("clicking on a link or button in sidebar collapses it", async function (assert) {
|
test("clicking on a link or button in sidebar collapses it", async function (assert) {
|
||||||
|
@ -40,7 +43,7 @@ acceptance("Sidebar - Mobile - User with sidebar enabled", function (needs) {
|
||||||
await click(".sidebar-section-link-tracked");
|
await click(".sidebar-section-link-tracked");
|
||||||
|
|
||||||
assert.ok(
|
assert.ok(
|
||||||
!exists(".sidebar-container"),
|
!exists(".sidebar-hamburger-dropdown"),
|
||||||
"sidebar is collapsed when a button in sidebar is clicked"
|
"sidebar is collapsed when a button in sidebar is clicked"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -48,28 +51,11 @@ acceptance("Sidebar - Mobile - User with sidebar enabled", function (needs) {
|
||||||
await click(".sidebar-section-header-link");
|
await click(".sidebar-section-header-link");
|
||||||
|
|
||||||
assert.ok(
|
assert.ok(
|
||||||
!exists(".sidebar-container"),
|
!exists(".sidebar-hamburger-dropdown"),
|
||||||
"sidebar is collapsed when a link in sidebar is clicked"
|
"sidebar is collapsed when a link in sidebar is clicked"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("collapsing sidebar sections does not collapse sidebar", async function (assert) {
|
|
||||||
await visit("/");
|
|
||||||
|
|
||||||
await click(".hamburger-dropdown");
|
|
||||||
await click(".sidebar-section-header-caret");
|
|
||||||
|
|
||||||
assert.ok(
|
|
||||||
!exists(".sidebar-section-community .sidebar-section-content"),
|
|
||||||
"topics section is collapsed"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.ok(
|
|
||||||
exists(".sidebar-container"),
|
|
||||||
"sidebar is not collapsed when clicking on caret to collapse a section in sidebar"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("button to toggle between mobile and desktop view", async function (assert) {
|
test("button to toggle between mobile and desktop view", async function (assert) {
|
||||||
await visit("/");
|
await visit("/");
|
||||||
await click(".hamburger-dropdown");
|
await click(".hamburger-dropdown");
|
||||||
|
|
|
@ -601,31 +601,3 @@ div.menu-links-header {
|
||||||
color: var(--primary-med-or-secondary-med);
|
color: var(--primary-med-or-secondary-med);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sidebar-hamburger hybrid
|
|
||||||
|
|
||||||
.hamburger-menu.revamped {
|
|
||||||
--d-sidebar-highlight-color: var(--highlight-medium);
|
|
||||||
width: var(--d-sidebar-width);
|
|
||||||
|
|
||||||
.panel-body-content {
|
|
||||||
width: 100%;
|
|
||||||
min-width: 0; // prevent content blowing out width
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-section-wrapper {
|
|
||||||
.sidebar-section-header-button {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-section-link.active {
|
|
||||||
font-weight: normal;
|
|
||||||
color: var(--primary-high);
|
|
||||||
background: var(--tertiary-low);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-footer-wrapper {
|
|
||||||
padding: 0.5em 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hamburger-menu.revamped {
|
.hamburger-panel .revamped {
|
||||||
.sidebar-footer-wrapper {
|
.sidebar-footer-wrapper {
|
||||||
background: var(--secondary);
|
background: var(--secondary);
|
||||||
.sidebar-footer-container {
|
.sidebar-footer-container {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
.sidebar-more-section-links-details {
|
.sidebar-more-section-links-details {
|
||||||
margin-left: 1.5em;
|
|
||||||
|
|
||||||
.sidebar-more-section-links-details-summary {
|
.sidebar-more-section-links-details-summary {
|
||||||
padding: 0.35em 0.5em;
|
padding: 0.35em 0.5em;
|
||||||
color: var(--primary-high);
|
color: var(--primary-high);
|
||||||
|
@ -41,3 +39,9 @@
|
||||||
border-top: 1.5px solid var(--primary-low);
|
border-top: 1.5px solid var(--primary-low);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#main-outlet-wrapper {
|
||||||
|
.sidebar-more-section-links-details {
|
||||||
|
margin-left: 1.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,3 +7,31 @@
|
||||||
max-height: calc(100vh - 100px);
|
max-height: calc(100vh - 100px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sidebar-hamburger hybrid
|
||||||
|
|
||||||
|
.hamburger-panel .revamped {
|
||||||
|
--d-sidebar-highlight-color: var(--highlight-medium);
|
||||||
|
width: var(--d-sidebar-width);
|
||||||
|
|
||||||
|
.panel-body-content {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0; // prevent content blowing out width
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-section-wrapper {
|
||||||
|
.sidebar-section-header-button {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-section-link.active {
|
||||||
|
font-weight: normal;
|
||||||
|
color: var(--primary-high);
|
||||||
|
background: var(--tertiary-low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-footer-wrapper {
|
||||||
|
padding: 0.5em 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -140,54 +140,3 @@ blockquote {
|
||||||
#simple-container {
|
#simple-container {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sidebar styles
|
|
||||||
|
|
||||||
#main-outlet-wrapper {
|
|
||||||
grid-template-columns: minmax(0, 100vw);
|
|
||||||
grid-template-areas: "content";
|
|
||||||
gap: 0;
|
|
||||||
|
|
||||||
.sidebar-wrapper {
|
|
||||||
width: 0;
|
|
||||||
transition: width 0.2s ease-in-out;
|
|
||||||
z-index: z("modal", "content");
|
|
||||||
grid-area: content;
|
|
||||||
justify-self: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-container {
|
|
||||||
padding-bottom: 6.6em; // extra space to watch out for navbar
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body.has-sidebar-page {
|
|
||||||
.d-header-wrap {
|
|
||||||
// edits the z-index when the sidebar is open:
|
|
||||||
// header
|
|
||||||
// sidebar & body overlay
|
|
||||||
// composer
|
|
||||||
z-index: z("modal", "content") + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-outlet-wrapper {
|
|
||||||
.sidebar-wrapper {
|
|
||||||
width: var(--d-sidebar-width);
|
|
||||||
margin-right: -10px; // compensate for main-outlet-wrapper padding
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-outlet {
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
background: rgb(0, 0, 0); // always a black overlay
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: z("modal", "overlay");
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue