DEV: First desktop design interface pass at experimental sidebar (#16590)

Co-authored-by: awesomerobot <kris.aubuchon@discourse.org>
This commit is contained in:
Alan Guo Xiang Tan 2022-05-05 11:19:46 +08:00 committed by GitHub
parent 48481dd6ed
commit 36dcf80aff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 187 additions and 17 deletions

View File

@ -0,0 +1,3 @@
import GlimmerComponent from "discourse/components/glimmer";
export default class Sidebar extends GlimmerComponent {}

View File

@ -6,6 +6,12 @@ export default Controller.extend({
showTop: true,
showFooter: false,
router: service(),
showSidebar: true,
@discourseComputed("showSidebar", "currentUser.experimental_sidebar_enabled")
mainOutletWrapperClasses(showSidebar, experimentalSidebarEnabled) {
return showSidebar && experimentalSidebarEnabled ? "has-sidebar" : "";
},
@discourseComputed
canSignUp() {

View File

@ -37,6 +37,10 @@ const ApplicationRoute = DiscourseRoute.extend(OpenComposer, {
});
},
toggleSidebar() {
this.controllerFor("application").toggleProperty("showSidebar");
},
toggleMobileView() {
mobile.toggleMobileView();
},

View File

@ -8,26 +8,34 @@
showKeyboard=(route-action "showKeyboardShortcutsHelp")
toggleMobileView=(route-action "toggleMobileView")
toggleAnonymous=(route-action "toggleAnonymous")
logout=(route-action "logout")}}
logout=(route-action "logout")
toggleSidebar=(route-action "toggleSidebar")
}}
{{software-update-prompt}}
{{plugin-outlet name="below-site-header" connectorTagName="div" args=(hash currentPath=router._router.currentPath)}}
<div id="main-outlet" class="wrap" role="main">
{{plugin-outlet name="above-main-container" connectorTagName="div"}}
<div class="container" id="main-container">
{{#if showTop}}
{{custom-html name="top"}}
{{/if}}
{{notification-consent-banner}}
{{pwa-install-banner}}
{{global-notice}}
{{create-topics-notice}}
{{plugin-outlet name="top-notices" connectorTagName="div" args=(hash currentPath=router._router.currentPath)}}
</div>
<div id="main-outlet-wrapper" class="wrap {{mainOutletWrapperClasses}}" role="main">
{{#if currentUser.experimental_sidebar_enabled}}
<Sidebar @shouldDisplay={{showSidebar}} />
{{/if}}
{{outlet}}
{{outlet "user-card"}}
<div id="main-outlet">
{{plugin-outlet name="above-main-container" connectorTagName="div"}}
<div class="container" id="main-container">
{{#if showTop}}
{{custom-html name="top"}}
{{/if}}
{{notification-consent-banner}}
{{pwa-install-banner}}
{{global-notice}}
{{create-topics-notice}}
{{plugin-outlet name="top-notices" connectorTagName="div" args=(hash currentPath=router._router.currentPath)}}
</div>
{{outlet}}
{{outlet "user-card"}}
</div>
</div>
{{plugin-outlet name="above-footer" connectorTagName="div" args=(hash showFooter=showFooter)}}

View File

@ -0,0 +1,6 @@
{{#if @shouldDisplay}}
<div class="sidebar-wrapper">
<div class="sidebar-container">
</div>
</div>
{{/if}}

View File

@ -4,6 +4,9 @@ import hbs from "discourse/widgets/hbs-compiler";
createWidget("header-contents", {
tagName: "div.contents.clearfix",
template: hbs`
{{#if attrs.sidebarEnabled}}
{{sidebar-toggle attrs=attrs}}
{{/if}}
{{home-logo attrs=attrs}}
{{#if attrs.topic}}
{{header-topic-info attrs=attrs}}

View File

@ -400,7 +400,12 @@ export default createWidget("header", {
return panels;
};
let contentsAttrs = { contents, minimized: !!attrs.topic };
let contentsAttrs = {
contents,
minimized: !!attrs.topic,
sidebarEnabled: this.currentUser?.experimental_sidebar_enabled,
};
return h(
"div.wrap",
this.attach("header-contents", Object.assign({}, attrs, contentsAttrs))

View File

@ -0,0 +1,16 @@
import { createWidget } from "discourse/widgets/widget";
export default createWidget("sidebar-toggle", {
tagName: "span.header-sidebar-toggle",
html() {
return [
this.attach("button", {
title: "",
icon: "bars",
action: "toggleSidebar",
className: "btn btn-flat",
}),
];
},
});

View File

@ -0,0 +1,65 @@
import { click, visit } from "@ember/test-helpers";
import {
acceptance,
conditionalTest,
exists,
} from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import { isLegacyEmber } from "discourse-common/config/environment";
acceptance("Sidebar - Anon User", function () {
// Don't show sidebar for anon user until we know what we want to display
test("sidebar is not displayed", async function (assert) {
await visit("/");
assert.ok(!exists("#main-outlet-wrapper.has-sidebar"));
assert.ok(!exists(".sidebar-wrapper"));
});
});
acceptance("Sidebar - User with sidebar disabled", function (needs) {
needs.user({ experimental_sidebar_enabled: false });
conditionalTest(
"sidebar is not displayed",
!isLegacyEmber(),
async function (assert) {
await visit("/");
assert.ok(!exists("#main-outlet-wrapper.has-sidebar"));
assert.ok(!exists(".sidebar-wrapper"));
}
);
});
acceptance("Sidebar - User with sidebar enabled", function (needs) {
needs.user({ experimental_sidebar_enabled: true });
conditionalTest(
"hiding and displaying sidebar",
!isLegacyEmber(),
async function (assert) {
await visit("/");
assert.ok(
exists("#main-outlet-wrapper.has-sidebar"),
"adds sidebar utility class on main outlet wrapper"
);
assert.ok(exists(".sidebar-wrapper"), "displays the sidebar by default");
await click(".header-sidebar-toggle .btn");
assert.ok(
!exists("#main-outlet-wrapper.has-sidebar"),
"removes sidebar utility class from main outlet wrapper"
);
assert.ok(!exists(".sidebar-wrapper"), "hides the sidebar");
await click(".header-sidebar-toggle .btn");
assert.ok(exists(".sidebar-wrapper"), "displays the sidebar");
}
);
});

View File

@ -44,6 +44,7 @@
@import "search";
@import "share_link";
@import "shared-drafts";
@import "sidebar";
@import "tagging";
@import "tooltip";
@import "topic-admin-menu";

View File

@ -651,6 +651,7 @@ table {
#main-outlet {
padding-top: 2.5em;
grid-area: content;
}
#main {

View File

@ -14,7 +14,6 @@
backface-visibility: hidden; /** do magic for scrolling performance **/
> .wrap {
box-sizing: border-box;
width: 100%;
height: 100%;

View File

@ -0,0 +1,40 @@
.header-sidebar-toggle {
margin-right: 1em;
margin-left: -10px;
button {
position: relative;
font-size: var(--font-up-2);
.discourse-no-touch & {
&:hover {
background: var(--primary-low);
.d-icon {
color: var(--primary-medium);
}
}
}
}
}
.sidebar-wrapper {
grid-area: sidebar;
position: sticky;
top: var(--header-offset);
height: calc(100vh - var(--header-offset));
align-self: start;
overflow-y: auto;
background-color: var(--primary-very-low);
}
.sidebar-container {
box-sizing: border-box;
height: 100%;
width: 240px;
padding: 1em;
}
.sidebar-toggle {
display: flex;
justify-content: flex-end;
}

View File

@ -182,3 +182,16 @@ input {
min-width: 0;
}
}
#main-outlet-wrapper {
display: grid;
grid-template-areas: "content";
grid-template-columns: 1fr;
gap: 0;
&.has-sidebar {
grid-template-areas: "sidebar content";
grid-template-columns: 240px 1fr;
gap: 0 2em;
}
}