discourse/app/assets/stylesheets/common/base/menu-panel.scss
Alan Guo Xiang Tan 7a05a9d411
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.
2022-08-16 13:45:32 +08:00

604 lines
11 KiB
SCSS

.menu-panel.slide-in {
position: fixed;
right: 0;
box-shadow: shadow("header");
.panel-body {
width: 100%;
}
}
.header-cloak {
display: none;
}
.menu-panel.drop-down {
position: absolute;
// positions are relative to the .d-header .panel div
top: 100%; // directly underneath .panel
right: -10px; // 10px to the right of .panel - adjust as needed
max-height: 80vh;
}
.menu-panel {
border: 1px solid var(--primary-low);
box-shadow: shadow("menu-panel");
background-color: var(--secondary);
z-index: z("header");
padding: 0.5em;
width: 320px;
overflow: hidden;
display: flex;
flex-direction: column;
hr {
margin: 3px 0;
}
.panel-header {
position: absolute;
right: 20px;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
.panel-body {
display: flex;
touch-action: pan-y pinch-zoom;
overflow: hidden;
height: 100%;
}
.panel-body-contents {
max-height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
.panel-body-bottom {
display: flex;
flex: 1 0 0%; // safari height fix
margin-top: 0.5em;
flex-wrap: wrap;
.show-all {
display: flex;
flex: 1 1 auto;
button {
width: 100%;
}
}
.notifications-dismiss {
margin-left: 0.5em;
}
.btn {
background-color: var(--primary-very-low);
color: var(--primary-high);
&:hover {
background: var(--primary-low);
color: var(--primary);
}
}
}
.badge-notification {
vertical-align: text-bottom;
}
}
.user-menu.revamped {
right: 0;
width: 320px;
padding: 0;
.panel-body-bottom {
flex: 0;
}
.menu-tabs-container {
display: flex;
flex-direction: column;
justify-content: space-between;
border-left: 1px solid var(--primary-low);
padding: 0.75em 0;
}
.tabs-list {
display: flex;
flex-direction: column;
.btn {
display: flex;
padding: 0.857em;
position: relative;
.d-icon {
color: var(--primary-medium);
}
.badge-notification {
background-color: var(--tertiary-med-or-tertiary);
position: absolute;
right: 6px;
top: 6px;
font-size: var(--font-down-3);
}
&.active {
background-color: var(--tertiary-low);
}
&:hover {
background-color: var(--highlight-medium);
}
}
}
.panel-body-contents {
display: flex;
flex-direction: row;
}
.quick-access-panel {
width: 320px;
padding: 0.75em;
justify-content: space-between;
box-sizing: border-box;
.double-user,
.multi-user {
white-space: unset;
}
.item-label {
color: var(--primary);
}
li {
background-color: var(--secondary);
&.unread,
&.pending {
background-color: var(--tertiary-low);
}
&:hover {
background-color: var(--highlight-medium);
outline: none;
}
&:focus-within {
background: var(--highlight-medium);
a {
// we don't need the link focus because we're styling the parent
outline: 0;
}
}
}
}
}
// remove when the widgets-based implementation of the user menu is removed
.user-menu:not(.revamped) {
.quick-access-panel {
li {
span:first-child {
color: var(--primary);
}
}
}
}
.hamburger-panel {
a.widget-link {
width: 100%;
box-sizing: border-box;
@include ellipsis;
}
.panel-body {
overflow-y: auto;
}
span.badge-category {
max-width: 100px;
}
}
.menu-links.columned {
li {
width: 50%;
float: left;
}
}
.menu-panel {
.widget-link,
.categories-link {
padding: 0.25em 0.5em;
display: block;
color: var(--primary);
&:hover,
&:focus {
background-color: var(--highlight-medium);
outline: none;
}
.d-icon {
color: var(--primary-medium);
}
.new {
font-size: $font-down-1;
margin-left: 0.5em;
color: var(--primary-med-or-secondary-med);
}
&.show-help,
&.filter {
color: var(--tertiary);
}
}
li.category-link {
float: left;
background-color: transparent;
display: inline-flex;
align-items: center;
padding: 0.25em 0.5em;
width: 50%;
box-sizing: border-box;
a {
display: inline-flex;
&:hover,
&:focus {
background: transparent;
.category-name {
color: var(--primary);
}
}
}
.badge-notification {
color: var(--primary-med-or-secondary-med);
background-color: transparent;
display: inline;
padding: 0;
font-size: $font-down-1;
line-height: $line-height-large;
}
.badge-wrapper {
&.bar,
&.bullet {
color: var(--primary);
padding: 0 0 0 0.15em;
}
&.box {
color: var(--secondary);
+ a.badge.badge-notification {
padding-top: 2px;
}
span {
z-index: z("base") * -1;
}
}
}
}
// note these topic counts only appear for anons in the category hamburger drop down
b.topics-count {
color: var(--primary-med-or-secondary-med);
font-weight: normal;
font-size: $font-down-1;
}
div.discourse-tags {
font-size: $font-down-1;
}
}
.user-menu {
.quick-access-panel {
width: 100%;
display: flex;
flex-direction: column;
min-height: 0;
max-height: 100%;
border-top: 1px solid var(--primary-low);
padding-top: 0.75em;
margin-top: -1px;
&:focus {
outline: none;
}
h3 {
padding: 0 0.4em;
font-weight: bold;
margin: 0.5em 0;
}
.d-icon,
&:hover .d-icon {
color: var(--primary-medium);
}
.icon {
color: var(--primary-high);
}
.btn-primary {
.d-icon {
color: var(--secondary);
}
}
ul {
display: flex;
flex-flow: column wrap;
overflow: hidden;
max-height: 100%;
}
li {
background-color: var(--tertiary-low);
box-sizing: border-box;
list-style-type: none;
// This is until other languages remove the HTML from within
// notifications. It can then be removed
div .fa {
display: none;
}
span.double-user,
// e.g., "username, username2"
span.multi-user
// e.g., "username, username2, and n others"
{
display: inline-flex;
max-width: 100%;
align-items: baseline;
white-space: nowrap;
}
span.multi-user
// e.g., "username, username2, and n others"
{
span.multi-username:nth-of-type(2) {
// margin between username2 and "and n others"
margin-right: 0.25em;
}
}
// truncate when usernames are very long
span.multi-username {
@include ellipsis;
flex: 0 1 auto;
min-width: 1.2em;
max-width: 10em;
&:nth-of-type(2) {
// margin for comma between username and username2
margin-left: 0.25em;
}
}
&:hover {
background-color: var(--highlight-medium);
outline: none;
}
&:focus-within {
background: var(--highlight-medium);
a {
// we don't need the link focus because we're styling the parent
outline: 0;
}
.btn-flat:focus {
// undo default btn-flat style
background: transparent;
}
}
a {
display: flex;
margin: 0.25em;
padding: 0em 0.25em;
}
button {
padding: 0.25em 0.5em;
}
a,
button {
> div {
overflow: hidden; // clears the text from wrapping below icons
overflow-wrap: anywhere;
@supports not (overflow-wrap: anywhere) {
word-break: break-word;
}
// Truncate items with more than 2 lines.
@include line-clamp(2);
}
}
p {
margin: 0;
overflow: hidden;
}
}
li:not(.show-all) {
padding: 0;
align-self: flex-start;
width: 100%;
.d-icon {
padding-top: 0.2em;
margin-right: 0.5em;
}
img.emoji {
height: 1em;
width: 1em;
padding-top: 0.2em;
margin-right: 0.5em;
}
}
.is-warning {
.d-icon-far-envelope {
color: var(--danger);
}
}
.read {
background-color: var(--secondary);
}
.none {
padding-top: 5px;
}
.spinner-container {
min-height: 2em;
}
.spinner {
width: 20px;
height: 20px;
border-width: 2px;
margin: 0 auto;
}
.show-all a {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
min-height: 30px;
color: var(--primary-med-or-secondary-high);
background: var(--blend-primary-secondary-5);
&:hover {
color: var(--primary);
background: var(--primary-low);
}
}
/* as a big ol' click target, don't let text inside be selected */
@include unselectable;
&.quick-access-profile {
display: inline;
li:not(.show-all) a {
color: var(--primary);
display: flex;
}
ul button {
line-height: 1.4; // match 'ul a' link height
width: 100%;
display: flex;
}
@media screen and (max-height: 360px) {
// two column grid to avoid scroll
ul {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-gap: 0 1em;
a {
@include ellipsis;
> div {
display: block;
}
}
button {
span:not(.relative-date) {
@include ellipsis;
}
}
}
li:not(.show-all) a {
color: var(--primary);
display: flex;
}
}
}
}
}
div.menu-links-header {
width: 100%;
.menu-links-row {
box-sizing: border-box;
display: flex;
width: 100%;
z-index: 2;
justify-content: space-between;
.glyphs {
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
width: 100%;
justify-content: space-between;
padding: 0;
button {
display: flex;
flex: 1 1 auto;
padding: 0.65em 0.25em 0.75em;
justify-content: center;
svg {
pointer-events: none;
}
}
}
button {
// This is to make sure active and inactive tab icons have the same
// size. `box-sizing` does not work and I have no idea why.
border: 1px solid transparent;
&:not(.active):hover {
border-bottom: 0;
margin-top: -1px;
}
}
button.active {
border: 1px solid var(--primary-low);
border-bottom: 1px solid var(--secondary);
position: relative;
.d-icon {
color: var(--primary-high);
}
&:hover {
background-color: inherit;
}
}
}
button:hover,
button:focus {
background-color: var(--primary-low);
outline: none;
&.active {
background-color: var(--primary-very-low);
}
}
button {
padding: 0.3em 0.5em;
}
.glyphs {
display: table-cell;
width: auto;
text-align: center;
}
.glyphs:first-child {
text-align: left;
}
.glyphs:last-child {
text-align: right;
}
.fa,
button {
color: var(--primary-med-or-secondary-med);
}
}