DEV: First desktop design interface pass at experimental sidebar take 2. (#16647)

This commit is contained in:
Alan Guo Xiang Tan 2022-05-05 14:35:08 +08:00 committed by GitHub
parent aa5d90a554
commit b35cf7cc0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 192 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, showTop: true,
showFooter: false, showFooter: false,
router: service(), router: service(),
showSidebar: true,
@discourseComputed("showSidebar", "currentUser.experimental_sidebar_enabled")
mainOutletWrapperClasses(showSidebar, experimentalSidebarEnabled) {
return showSidebar && experimentalSidebarEnabled ? "has-sidebar" : "";
},
@discourseComputed @discourseComputed
canSignUp() { canSignUp() {

View File

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

View File

@ -8,26 +8,34 @@
showKeyboard=(route-action "showKeyboardShortcutsHelp") showKeyboard=(route-action "showKeyboardShortcutsHelp")
toggleMobileView=(route-action "toggleMobileView") toggleMobileView=(route-action "toggleMobileView")
toggleAnonymous=(route-action "toggleAnonymous") toggleAnonymous=(route-action "toggleAnonymous")
logout=(route-action "logout")}} logout=(route-action "logout")
toggleSidebar=(route-action "toggleSidebar")
}}
{{software-update-prompt}} {{software-update-prompt}}
{{plugin-outlet name="below-site-header" connectorTagName="div" args=(hash currentPath=router._router.currentPath)}} {{plugin-outlet name="below-site-header" connectorTagName="div" args=(hash currentPath=router._router.currentPath)}}
<div id="main-outlet" class="wrap" role="main"> <div id="main-outlet-wrapper" class="wrap {{mainOutletWrapperClasses}}" role="main">
{{plugin-outlet name="above-main-container" connectorTagName="div"}} {{#if currentUser.experimental_sidebar_enabled}}
<div class="container" id="main-container"> <Sidebar @shouldDisplay={{showSidebar}} />
{{#if showTop}} {{/if}}
{{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}} <div id="main-outlet">
{{outlet "user-card"}} {{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> </div>
{{plugin-outlet name="above-footer" connectorTagName="div" args=(hash showFooter=showFooter)}} {{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", { createWidget("header-contents", {
tagName: "div.contents.clearfix", tagName: "div.contents.clearfix",
template: hbs` template: hbs`
{{#if attrs.sidebarEnabled}}
{{sidebar-toggle attrs=attrs}}
{{/if}}
{{home-logo attrs=attrs}} {{home-logo attrs=attrs}}
{{#if attrs.topic}} {{#if attrs.topic}}
{{header-topic-info attrs=attrs}} {{header-topic-info attrs=attrs}}

View File

@ -400,7 +400,12 @@ export default createWidget("header", {
return panels; return panels;
}; };
let contentsAttrs = { contents, minimized: !!attrs.topic }; const contentsAttrs = {
contents,
minimized: !!attrs.topic,
sidebarEnabled: this.currentUser?.experimental_sidebar_enabled,
};
return h( return h(
"div.wrap", "div.wrap",
this.attach("header-contents", Object.assign({}, attrs, contentsAttrs)) 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 "search";
@import "share_link"; @import "share_link";
@import "shared-drafts"; @import "shared-drafts";
@import "sidebar";
@import "tagging"; @import "tagging";
@import "tooltip"; @import "tooltip";
@import "topic-admin-menu"; @import "topic-admin-menu";

View File

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

View File

@ -0,0 +1,42 @@
.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);
}
}
}
}
}
#main-outlet-wrapper {
.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,20 @@ input {
min-width: 0; 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;
}
#main-outlet {
grid-area: content;
}
}