UX: Add icons to all section links in Sidebar (#18378)

This commit introduces an icon to all links in the sidebar. If an icon has not been configured, we will fall back to a generic "link" icon. As part of this commit, we also standardised the size of each prefix to 20px by 20px and set a fix margin. This is to allow sufficient space for text prefixes and image prefixes to be displayed. 

Tests have been intentionally left out for now as I don't feel like asserting for the icons will bring much value at this point. Time shall prove me wrong.

Co-authored-by: awesomerobot <kris.aubuchon@discourse.org>
This commit is contained in:
Alan Guo Xiang Tan 2022-09-29 12:28:01 +08:00 committed by GitHub
parent b6dfe5e394
commit f1cbc23f1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 268 additions and 130 deletions

View File

@ -8,6 +8,8 @@
@route={{sectionLink.route}}
@content={{sectionLink.text}}
@currentWhen={{sectionLink.currentWhen}}
@prefixType={{sectionLink.prefixType}}
@prefixValue={{sectionLink.prefixValue}}
@models={{sectionLink.models}} >
</Sidebar::SectionLink>
{{/each}}

View File

@ -2,4 +2,6 @@
@linkName="all-categories"
@content={{i18n "sidebar.all_categories"}}
@route="discovery.categories"
@prefixType="icon"
@prefixValue="list"
/>

View File

@ -2,4 +2,6 @@
@linkName="all-tags"
@content={{i18n "sidebar.all_tags"}}
@route="tags"
@prefixType="icon"
@prefixValue="list"
/>

View File

@ -22,7 +22,9 @@
@currentWhen={{sectionLink.currentWhen}}
@badgeText={{sectionLink.badgeText}}
@model={{sectionLink.model}}
@models={{sectionLink.models}} />
@models={{sectionLink.models}}
@prefixType={{sectionLink.prefixType}}
@prefixValue={{sectionLink.prefixValue}} />
{{/each}}
<Sidebar::MoreSectionLinks @sectionLinks={{this.moreSectionLinks}} @secondarySectionLinks={{this.moreSecondarySectionLinks}} />

View File

@ -3,7 +3,7 @@
<div class="panel-body">
<div class="panel-body-contents">
<div class="sidebar-hamburger-dropdown">
<Sidebar::Sections @currentUser={{this.currentUser}} @collapsableSections={{false}} />
<Sidebar::Sections @currentUser={{this.currentUser}} @collapsableSections={{true}} />
<Sidebar::Footer @tagName="" />
</div>
</div>

View File

@ -8,4 +8,6 @@
@currentWhen={{@sectionLink.currentWhen}}
@badgeText={{@sectionLink.badgeText}}
@model={{@sectionLink.model}}
@models={{@sectionLink.models}} />
@models={{@sectionLink.models}}
@prefixType={{@sectionLink.prefixType}}
@prefixValue={{@sectionLink.prefixValue}} />

View File

@ -4,6 +4,10 @@
<details class="sidebar-more-section-links-details" {{on "toggle" this.toggleSectionLinks}}>
<summary class="sidebar-more-section-links-details-summary sidebar-row" >
<span class="sidebar-more-section-links-icon-wrapper">
{{d-icon "ellipsis-v"}}
</span>
{{i18n "sidebar.more"}}
</summary>

View File

@ -0,0 +1,21 @@
{{#if @prefixValue}}
<span class={{concat-class "sidebar-section-link-prefix" @prefixType @prefixCSSClass}} style={{@prefixCSS}}>
{{#if (eq @prefixType "image")}}
<img src={{@prefixValue}} class="prefix-image">
{{/if}}
{{#if (eq @prefixType "text")}}
<span class="prefix-text">
{{@prefixValue}}
</span>
{{/if}}
{{#if (eq @prefixType "icon")}}
{{d-icon @prefixValue class="prefix-icon"}}
{{/if}}
{{#if @prefixBadge}}
{{d-icon @prefixBadge class="prefix-badge"}}
{{/if}}
</span>
{{/if}}

View File

@ -0,0 +1,3 @@
import templateOnly from "@ember/component/template-only";
export default templateOnly();

View File

@ -1,6 +1,14 @@
<div class="sidebar-section-link-wrapper">
{{#if @href}}
<a href={{@href}} rel="noopener noreferrer" target="_blank" class={{this.classNames}} title={{@title}}>
<Sidebar::SectionLinkPrefix
@prefixType={{@prefixType}}
@prefixValue={{@prefixValue}}
@prefixCSSClass={{@prefixCSSClass}}
@prefixCSS={{this.prefixCSS}}
@prefixBadge={{@prefixBadge}}
/>
<span class="sidebar-section-link-content-text">
{{@content}}
</span>
@ -14,25 +22,14 @@
@current-when={{@currentWhen}}
@title={{@title}}
>
{{#if @prefixValue}}
<span class="sidebar-section-link-prefix {{@prefixType}} {{@prefixCSSClass}}" style={{this.prefixCSS}}>
{{#if (eq @prefixType "image")}}
<img src={{@prefixValue}} class="prefix-image">
{{/if}}
{{#if (eq @prefixType "text")}}
{{@prefixValue}}
{{/if}}
{{#if (eq @prefixType "icon")}}
{{d-icon @prefixValue class="prefix-icon"}}
{{/if}}
{{#if @prefixBadge}}
{{d-icon @prefixBadge class="prefix-badge"}}
{{/if}}
</span>
{{/if}}
<Sidebar::SectionLinkPrefix
@prefixType={{@prefixType}}
@prefixValue={{@prefixValue}}
@prefixCSSClass={{@prefixCSSClass}}
@prefixCSS={{this.prefixCSS}}
@prefixBadge={{@prefixBadge}}
/>
<span class="sidebar-section-link-content-text">
{{@content}}
@ -45,7 +42,7 @@
{{/if}}
{{#if @suffixValue}}
<span class="sidebar-section-link-suffix {{@suffixType}} {{@suffixCSSClass}}">
<span class={{concat-class "sidebar-section-link-suffix" @suffixType @suffixCSSClass}}>
{{#if (eq @suffixType "icon")}}
{{d-icon @suffixValue}}
{{/if}}

View File

@ -1,11 +1,12 @@
<div class={{concat "sidebar-section-wrapper sidebar-section-" @sectionName}}>
<div class="sidebar-section-header-wrapper sidebar-row">
<Sidebar::SectionHeader @collapsable={{@collapsable}} @toggleSectionDisplay={{this.toggleSectionDisplay}}>
<span class="sidebar-section-header-caret">
{{#if @collapsable}}
{{#if @collapsable}}
<span class="sidebar-section-header-caret">
{{d-icon this.headerCaretIcon}}
{{/if}}
</span>
</span>
{{/if}}
<span class="sidebar-section-header-text">
{{@headerLinkText}}
</span>

View File

@ -13,6 +13,8 @@
@class={{personalMessageSectionLink.class}}
@route={{personalMessageSectionLink.route}}
@model={{personalMessageSectionLink.model}}
@prefixType={{personalMessageSectionLink.prefixType}}
@prefixValue={{personalMessageSectionLink.prefixValue}}
@currentWhen={{personalMessageSectionLink.currentWhen}}
@content={{personalMessageSectionLink.text}} />
{{/if}}
@ -25,6 +27,8 @@
@linkName={{groupMessageSectionLink.name}}
@class={{groupMessageSectionLink.class}}
@route={{groupMessageSectionLink.route}}
@prefixType={{groupMessageSectionLink.prefixType}}
@prefixValue={{groupMessageSectionLink.prefixValue}}
@models={{groupMessageSectionLink.models}}
@currentWhen={{groupMessageSectionLink.currentWhen}}
@content={{groupMessageSectionLink.text}} />

View File

@ -13,6 +13,8 @@
@title={{sectionLink.title}}
@content={{sectionLink.text}}
@currentWhen={{sectionLink.currentWhen}}
@prefixType={{sectionLink.prefixType}}
@prefixValue={{sectionLink.prefixValue}}
@badgeText={{sectionLink.badgeText}}
@models={{sectionLink.models}} >
</Sidebar::SectionLink>

View File

@ -93,6 +93,20 @@ export default class BaseCommunitySectionLink {
*/
get badgeText() {}
/**
* @private
*/
get prefixType() {
return "icon";
}
/**
* @returns {string} The name of the fontawesome icon to be displayed before the link. Defaults to "link".
*/
get prefixValue() {
return "link";
}
_notImplemented() {
throw "not implemented";
}

View File

@ -18,4 +18,7 @@ export default class AboutSectionLink extends BaseSectionLink {
get text() {
return I18n.t("sidebar.sections.community.links.about.content");
}
get prefixValue() {
return "info-circle";
}
}

View File

@ -22,4 +22,8 @@ export default class BadgesSectionLink extends BaseSectionLink {
get shouldDisplay() {
return this.siteSettings.enable_badges;
}
get prefixValue() {
return "certificate";
}
}

View File

@ -71,4 +71,8 @@ export default class EverythingSectionLink extends BaseSectionLink {
return "discovery.latest";
}
}
get prefixValue() {
return "layer-group";
}
}

View File

@ -22,4 +22,8 @@ export default class FAQSectionLink extends BaseSectionLink {
get text() {
return I18n.t("sidebar.sections.community.links.faq.content");
}
get prefixValue() {
return "question-circle";
}
}

View File

@ -22,4 +22,8 @@ export default class GroupsSectionLink extends BaseSectionLink {
get shouldDisplay() {
return this.siteSettings.enable_group_directory;
}
get prefixValue() {
return "user-friends";
}
}

View File

@ -25,4 +25,8 @@ export default class UsersSectionLink extends BaseSectionLink {
(this.currentUser || !this.siteSettings.hide_user_profiles_from_public)
);
}
get prefixValue() {
return "users";
}
}

View File

@ -22,4 +22,8 @@ export default class AdminSectionLink extends BaseSectionLink {
get shouldDisplay() {
return this.currentUser?.staff;
}
get prefixValue() {
return "wrench";
}
}

View File

@ -62,4 +62,8 @@ export default class MyPostsSectionLink extends BaseSectionLink {
get _hasDraft() {
return this.draftCount > 0;
}
get prefixValue() {
return "user";
}
}

View File

@ -72,4 +72,8 @@ export default class TrackedSectionLink extends BaseSectionLink {
return "discovery.latest";
}
}
get prefixValue() {
return "bell";
}
}

View File

@ -71,4 +71,16 @@ export default class MessageSectionLink {
get _shouldTrack() {
return this.type === NEW || this.type === UNREAD;
}
get prefixType() {
if (this._isInbox) {
return "icon";
}
}
get prefixValue() {
if (this._isInbox) {
return "inbox";
}
}
}

View File

@ -64,4 +64,12 @@ export default class TagSectionLink {
});
}
}
get prefixType() {
return "icon";
}
get prefixValue() {
return "tag";
}
}

View File

@ -683,7 +683,7 @@ table {
}
#main-outlet {
padding-top: 2.5em;
padding-top: 1.5em;
}
#main {

View File

@ -12,9 +12,18 @@
list-style: none;
box-sizing: border-box;
.d-icon {
margin-left: auto;
color: var(--primary-medium);
.sidebar-more-section-links-icon-wrapper {
display: flex;
align-items: center;
justify-content: center;
width: var(--d-sidebar-section-link-prefix-width);
height: var(--d-sidebar-section-link-prefix-width);
margin-right: var(--d-sidebar-section-link-prefix-margin-right);
.d-icon {
color: var(--primary-medium);
font-size: var(--font-down-1);
}
}
&::before {
@ -35,7 +44,7 @@
margin: 0 calc(var(--d-sidebar-row-horizontal-padding) * 2 / 3);
.sidebar-row {
padding: calc(var(--d-sidebar-row-horizontal-padding) / 3);
padding: 0.33rem calc(var(--d-sidebar-row-horizontal-padding) / 3);
}
}

View File

@ -1,10 +1,14 @@
:root {
--d-sidebar-section-link-prefix-margin-right: 0.4rem;
--d-sidebar-section-link-prefix-width: 20px;
}
.sidebar-section-link-wrapper {
display: flex;
align-items: center;
position: relative;
.sidebar-section-link {
box-sizing: border-box;
display: inline-flex;
width: 100%;
align-items: center;
@ -19,8 +23,13 @@
&.active {
color: var(--primary);
font-weight: bold;
background: var(--d-sidebar-highlight-color);
.sidebar-section-link-prefix {
&.icon {
color: var(--primary-high);
}
}
}
.sidebar-section-link-content-badge {
@ -67,7 +76,10 @@
.sidebar-section-link-group-messages-unread,
.sidebar-section-link-group-messages-archive {
.sidebar-section-link-content-text {
margin-left: 0.5em;
margin-left: calc(
var(--d-sidebar-section-link-prefix-margin-right) +
var(--d-sidebar-section-link-prefix-width)
);
}
}
@ -78,45 +90,46 @@
}
.sidebar-section-link-prefix {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: var(--d-sidebar-section-link-prefix-width);
height: var(--d-sidebar-section-link-prefix-width);
margin-right: var(--d-sidebar-section-link-prefix-margin-right);
&.image {
position: absolute;
img {
border-radius: 50%;
width: 20px;
border-radius: 100%;
aspect-ratio: auto 20 / 20;
height: 20px;
margin-right: 0.5em;
}
+ .sidebar-section-link-content-text {
margin-left: calc(20px + 0.5em);
width: calc(var(--d-sidebar-section-link-prefix-width) - 2px);
height: calc(var(--d-sidebar-section-link-prefix-width) - 2px);
}
}
&.text {
border-radius: 100%;
background: rgba(var(--primary-rgb), 0.1);
text-align: center;
font-size: var(--font-down-1);
padding: 0.27em 0.47em;
margin-right: 0.25em;
position: absolute;
+ .sidebar-section-link-content-text {
margin-left: calc(20px + 0.5em);
.prefix-text {
display: flex;
align-items: center;
justify-content: center;
border-radius: 100%;
background: rgba(var(--primary-rgb), 0.1);
width: calc(var(--d-sidebar-section-link-prefix-width) - 2px);
height: calc(var(--d-sidebar-section-link-prefix-width) - 2px);
}
}
&.icon {
position: relative;
margin-right: 0.5em;
color: var(--primary-medium);
svg {
font-size: var(--font-down-1);
}
svg.prefix-badge {
.prefix-badge {
position: absolute;
background-color: transparent;
border-radius: 50%;
@ -126,7 +139,7 @@
width: 0.5rem;
top: -0.2em;
right: 0;
margin-right: -0.6em;
margin-right: -0.2em;
}
}
}

View File

@ -1,29 +1,51 @@
:root {
--d-sidebar-section-header-text-font-size: var(--font-up-1);
}
.sidebar-section-wrapper {
.discourse-no-touch & {
&:hover {
.sidebar-section-header-wrapper {
.btn.dropdown-select-box-header,
.sidebar-section-header-button {
opacity: 1;
}
}
}
}
.sidebar-section-header-wrapper {
display: flex;
box-sizing: border-box;
padding: 0;
.discourse-no-touch & {
&:hover {
background: var(--d-sidebar-highlight-color);
}
}
&:focus-within {
background: var(--d-sidebar-highlight-color);
}
.btn.dropdown-select-box-header,
.sidebar-section-header-button {
.discourse-no-touch & {
transition: all 0.25s;
opacity: 0;
}
background: transparent;
border: none;
margin-right: calc(var(--d-sidebar-row-horizontal-padding) / 3 * -1);
padding: calc(var(--d-sidebar-row-horizontal-padding) / 5)
calc(var(--d-sidebar-row-horizontal-padding) / 3);
margin-right: calc(var(--d-sidebar-row-horizontal-padding) / 1.5);
.d-icon {
font-size: var(--font-down-1);
color: var(--primary-medium);
margin: 0;
}
&:focus {
outline: none;
background: var(--primary-medium);
@ -31,6 +53,7 @@
color: var(--primary-very-low);
}
}
.discourse-no-touch & {
&:hover {
background: var(--primary-medium);
@ -44,16 +67,10 @@
.sidebar-section-header {
flex: 1 1 auto;
text-transform: uppercase;
font-weight: bold;
font-size: var(--font-1);
color: var(--primary);
align-items: center;
padding: calc(var(--d-sidebar-row-horizontal-padding) / 2)
calc(var(--d-sidebar-row-horizontal-padding) / 2)
calc(var(--d-sidebar-row-horizontal-padding) / 2)
var(--d-sidebar-row-horizontal-padding);
min-width: 0;
padding: 0;
&.sidebar-section-header-collapsable {
justify-content: flex-start;
@ -61,18 +78,25 @@
}
.sidebar-section-header-text {
font-weight: bold;
line-height: normal;
margin-right: 0.25em;
font-size: var(--d-sidebar-section-header-text-font-size);
@include ellipsis;
}
.sidebar-section-header-caret {
display: block;
width: 1.5em;
margin-left: -1.5em;
font-size: var(--font-down-2);
display: flex;
flex: 0 0 auto;
width: var(--d-sidebar-section-link-prefix-width);
height: var(--d-sidebar-section-link-prefix-width);
margin-right: var(--d-sidebar-section-link-prefix-margin-right);
align-items: center;
justify-content: center;
svg {
font-size: var(--font-down-1);
color: var(--primary-medium);
}
}
.select-kit-collection {
@ -93,9 +117,12 @@
.sidebar-section-message {
color: var(--primary);
padding-left: 1.4em;
}
.sidebar-section-content {
padding-bottom: 1em;
hr {
margin: 0em 1.5em;
}

View File

@ -2,14 +2,26 @@
--d-sidebar-width: #{$d-sidebar-width};
--d-sidebar-animation-time: 0.25s;
--d-sidebar-animation-ease: ease-in-out;
--d-sidebar-row-height: 30px;
// 1.25rem gets text left-aligned with the hamburger icon
--d-sidebar-row-horizontal-padding: 1.25rem;
--d-sidebar-row-vertical-padding: 0.33rem;
--d-sidebar-row-font-size: var(--font-down-1);
}
.sidebar-row {
box-sizing: border-box;
height: var(--d-sidebar-row-height);
padding: var(--d-sidebar-row-vertical-padding)
var(--d-sidebar-row-horizontal-padding);
align-items: center;
font-size: var(--d-sidebar-row-font-size);
}
.sidebar-wrapper {
display: flex;
--d-sidebar-highlight-color: var(--primary-low);
// 1.25rem gets text left-aligned with the hamburger icon
--d-sidebar-row-horizontal-padding: 1.25rem;
background-color: var(--primary-very-low);
background-color: var(--primary-50);
grid-area: sidebar;
position: sticky;
top: var(--header-offset);
@ -21,12 +33,6 @@
align-self: start;
overflow-y: auto;
.sidebar-row {
padding: 0.33rem var(--d-sidebar-row-horizontal-padding);
align-items: center;
font-size: var(--font-down-1);
}
.sidebar-container {
display: flex;
flex-direction: column;
@ -44,7 +50,7 @@
flex-direction: column;
box-sizing: border-box;
flex: 1;
padding: 1em 0;
padding: 1.5em 0 1em;
overflow-x: hidden;
overflow-y: overlay;
@ -83,17 +89,6 @@
}
.sidebar-hamburger-dropdown {
// note that these apply to mobile and desktop dropdowns
.sidebar-section-wrapper {
.sidebar-section-header-wrapper.sidebar-row {
padding-right: 0;
}
.sidebar-section-header {
padding: 0;
}
}
.discourse-no-touch & {
.sidebar-section-wrapper .sidebar-section-header-wrapper:hover,
.sidebar-section-wrapper .sidebar-section-header-wrapper:focus-within {

View File

@ -12,7 +12,6 @@
@import "menu-panel";
@import "modal";
@import "new-user";
@import "sidebar-section";
@import "topic-list";
@import "topic-post";
@import "topic";

View File

@ -195,7 +195,7 @@ body.has-sidebar-page {
#main-outlet-wrapper {
grid-template-columns: var(--d-sidebar-width) minmax(0, 1fr);
gap: 0 1em;
gap: 0 2em;
padding-left: 0;
}
}

View File

@ -13,14 +13,10 @@
.hamburger-panel .revamped {
--d-sidebar-highlight-color: var(--highlight-medium);
--d-sidebar-row-horizontal-padding: 0.5rem;
width: var(--d-sidebar-width);
.sidebar-row {
padding: 0.25rem var(--d-sidebar-row-horizontal-padding);
height: 27px;
align-items: center;
font-size: var(--font-down-1);
}
--d-sidebar-row-height: 30px;
// 1.25rem gets text left-aligned with the hamburger icon
--d-sidebar-row-horizontal-padding: 0.66rem;
--d-sidebar-row-vertical-padding: 0.33rem;
.panel-body-content {
width: 100%;

View File

@ -1,25 +0,0 @@
#main-outlet-wrapper {
.sidebar-section-wrapper {
.sidebar-section-header-button,
.sidebar-section-header-caret,
.sidebar-section-header-dropdown {
.discourse-no-touch & {
opacity: 0;
transition: opacity 0.25s;
transition-delay: 0.25s;
}
}
.discourse-no-touch & {
&:focus-within,
&:hover {
.sidebar-section-header-button,
.sidebar-section-header-caret,
.sidebar-section-header-dropdown {
opacity: 1;
transition-delay: 0s;
}
}
}
}
}

View File

@ -72,6 +72,9 @@
.hamburger-panel .revamped {
--d-sidebar-row-horizontal-padding: 1rem;
--d-sidebar-highlight-color: var(--primary-low);
--d-sidebar-row-font-size: var(--font-0);
--d-sidebar-row-height: 32px;
--d-sidebar-section-header-text-font-size: var(--font-0);
box-sizing: border-box;
padding: 0;
@ -79,18 +82,23 @@
.sidebar-hamburger-dropdown {
display: flex;
flex-direction: column;
padding-top: 0.5em;
}
}
.sidebar-row {
padding: 1.2rem var(--d-sidebar-row-horizontal-padding);
height: 27px;
align-items: center;
font-size: var(--font-0);
&.sidebar-section-message-wrapper {
padding-top: 0;
padding-bottom: 0.25em;
}
.sidebar-section-message {
padding: 0;
}
}
.sidebar-section-wrapper {
margin-bottom: 0.5em;
margin-bottom: 1.2em;
}
.sidebar-footer-wrapper {
@ -112,4 +120,8 @@
flex-direction: column;
box-sizing: border-box;
}
.sidebar-section-content {
padding-bottom: 0;
}
}

View File

@ -139,6 +139,7 @@ module SvgSprite
"hourglass-start",
"id-card",
"image",
"inbox",
"info-circle",
"italic",
"key",