discourse/app/assets/stylesheets/common/base/header.scss

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

456 lines
9.1 KiB
SCSS
Raw Normal View History

.d-header-wrap {
@include sticky;
top: 0;
z-index: z("header");
.footer-nav-ipad & {
top: var(--footer-nav-height, 0px);
}
}
.d-header {
display: flex;
align-items: center;
2017-09-06 22:47:48 +08:00
width: 100%;
z-index: z("header");
background-color: var(--header_background);
box-shadow: var(--shadow-header);
backface-visibility: hidden; /** do magic for scrolling performance **/
2017-09-06 22:47:48 +08:00
> .wrap {
box-sizing: border-box;
width: 100%;
height: 100%;
.contents {
display: flex;
align-items: center;
height: 100%;
.header-row {
width: 100%;
.logo-wrapper {
float: left;
}
.auth-buttons {
float: right;
margin-top: 0.4em;
.login-button,
.signup-button {
padding: 8px 14px;
}
}
}
}
}
2017-09-06 22:47:48 +08:00
.title {
--d-logo-height: 2.667em;
display: flex;
align-items: center;
height: 100%;
animation: fadein 0.5s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
// min-width acts as a placeholder if the small logo takes a while to load
// it prevents topic title from shifting after the small logo loads
// it's set to match the #site-logo height so square small logos don't resize when titles dock
min-width: var(--d-logo-height);
a,
a:visited {
color: var(--header_primary);
}
&:not(.title--minimized) {
// allows large logos to be hidden if there are too many other header elements
// this prioritizes nav elements, especially in cases of high zoom levels
overflow: hidden;
}
2017-09-06 22:47:48 +08:00
}
#site-logo {
height: var(--d-logo-height);
width: auto;
max-width: 100%;
object-fit: contain;
2017-09-06 22:47:48 +08:00
}
#site-text-logo {
margin: 0;
@include ellipsis;
}
.d-icon-home {
font-size: var(--font-up-6);
2017-09-06 22:47:48 +08:00
}
.panel {
position: relative;
display: flex;
flex: 0 0 auto;
margin-left: auto;
align-items: center;
2017-09-06 22:47:48 +08:00
}
.hamburger-panel,
.user-menu,
.search-menu {
width: 0; // Flexbox fix for Safari
}
2018-02-17 06:13:10 +08:00
.header-buttons {
display: flex;
align-items: center;
margin-top: 0.2em;
white-space: nowrap;
.auth-buttons {
display: flex;
}
2018-02-17 06:13:10 +08:00
}
.login-button,
.sign-up-button {
2017-09-06 22:47:48 +08:00
padding: 6px 10px;
.fa {
margin-right: 3px;
}
2017-09-06 22:47:48 +08:00
}
.login-button {
2017-09-06 22:47:48 +08:00
margin-left: 7px;
}
2017-09-06 23:29:43 +08:00
}
2017-09-06 22:47:48 +08:00
.header-dropdown-toggle,
.drop-down,
.panel-body {
.flagged-posts,
.reviewables {
background: var(--danger);
2018-02-21 06:31:02 +08:00
min-width: 6px;
2017-09-11 02:26:55 +08:00
}
}
2017-09-06 23:29:43 +08:00
.d-header-icons {
display: flex;
margin: 0 0 0 0.5em;
2017-09-06 23:29:43 +08:00
list-style: none;
.icon {
box-sizing: content-box;
appearance: none;
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 2.2857em;
height: 2.2857em;
padding: 0.2143em;
2017-09-06 23:29:43 +08:00
text-decoration: none;
cursor: pointer;
border: 1px solid transparent;
transition: all linear 0.15s;
outline: none;
img.avatar {
width: 2.1333em;
height: 2.1333em;
}
.discourse-no-touch &:hover,
.discourse-no-touch &:focus {
background-color: var(--primary-low);
2017-09-06 22:47:48 +08:00
border-top: 1px solid transparent;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
> .d-icon {
color: var(--primary-medium);
2019-02-01 08:31:09 +08:00
}
2017-09-06 23:29:43 +08:00
}
&:active {
color: var(--primary);
background-color: var(--primary-low);
2017-09-06 23:29:43 +08:00
}
}
.drop-down-mode & {
2017-09-06 23:29:43 +08:00
.active .icon {
position: relative;
background-color: var(--secondary);
2017-09-06 23:29:43 +08:00
cursor: default;
border-top: 1px solid var(--primary-low);
border-left: 1px solid var(--primary-low);
border-right: 1px solid var(--primary-low);
> .d-icon {
color: var(--primary-medium);
}
2017-09-06 23:29:43 +08:00
&:after {
display: block;
position: absolute;
top: 100%;
left: 0;
z-index: z("header") + 1; // Higher than .menu-panel
2017-09-06 23:29:43 +08:00
width: 100%;
height: 0;
content: "";
border-top: 1px solid var(--secondary);
2017-09-06 22:47:48 +08:00
}
2017-09-06 23:29:43 +08:00
&:hover {
border-bottom: none;
}
2017-09-06 22:47:48 +08:00
}
2017-09-06 23:29:43 +08:00
}
2017-09-06 23:29:43 +08:00
.d-icon {
width: 100%;
font-size: var(--font-up-4);
line-height: var(--line-height-large);
2017-09-06 23:29:43 +08:00
display: inline-block;
color: var(--header_primary-low-mid);
2017-09-06 22:47:48 +08:00
}
2017-09-06 23:29:43 +08:00
.notifications {
position: relative;
}
.header-dropdown-toggle {
position: relative;
}
.badge-notification {
border: 2px solid var(--header_background);
2017-09-06 23:29:43 +08:00
position: absolute;
z-index: z("base");
2017-09-06 23:29:43 +08:00
left: 0;
2018-01-13 06:27:38 +08:00
top: -4px;
2019-01-18 04:46:55 +08:00
min-width: 0.6em;
2017-09-06 23:29:43 +08:00
left: auto;
2018-01-13 06:27:38 +08:00
right: -3px;
&.with-icon {
&.new-pms {
background-color: var(--success);
}
&.new-reviewables {
background-color: var(--danger);
}
.d-icon {
color: var(--secondary);
font-size: var(--font-down-1);
width: 1em;
}
}
}
.unread-notifications {
background-color: var(--tertiary-med-or-tertiary);
2017-09-06 23:29:43 +08:00
}
.unread-high-priority-notifications {
2017-09-06 23:29:43 +08:00
left: auto;
right: 25px;
2017-09-06 22:47:48 +08:00
}
}
.header-sidebar-toggle {
button {
margin-right: 1em;
box-sizing: content-box; // matches other header icons
display: flex;
justify-content: center;
width: 2.2857em;
height: 2.2857em;
padding: 0.2143em;
&:focus,
.discourse-no-touch & {
&:hover {
background-color: var(--primary-low);
}
}
.d-icon {
width: 100%;
font-size: var(--font-up-4);
line-height: var(--line-height-large);
display: inline-block;
color: var(--header_primary-low-mid);
}
}
}
// topic info in the header
.extra-info-wrapper {
flex: 1 0 0;
display: flex;
align-items: center;
height: 100%;
line-height: var(--line-height-medium);
padding: 0 1.5em 0 0.5em;
// we need to hide overflow in both to truncate the title in a flexbox
overflow: hidden;
.extra-info {
overflow: hidden;
width: 100%;
animation: fadein 0.5s;
@media (prefers-reduced-motion) {
animation-duration: 0s;
}
}
.title-wrapper {
display: grid;
grid-template-areas:
"title title"
"categories extra";
grid-template-columns: auto minmax(2em, 1fr); // min must be as wide as ellipsis
align-items: baseline;
gap: 0 0.5em;
.header-title {
grid-area: title;
}
.categories-wrapper {
grid-area: categories;
}
.topic-header-extra {
grid-area: extra;
}
}
.topic-link {
color: var(--header_primary);
display: block;
@include ellipsis;
}
.topic-statuses {
.d-icon {
color: var(--header_primary-medium);
}
.d-icon-envelope {
color: var(--danger);
}
}
.header-title {
padding: 0;
margin: 0;
font-size: var(--font-up-3);
width: 100%;
}
.categories-wrapper {
display: inline-flex;
flex: 0 1 auto;
gap: 0 0.5em;
@include ellipsis;
}
.badge-category__wrapper {
min-width: 2.75em; // min needed for ellipsis
@include ellipsis;
.badge-category {
color: var(--header_primary-high);
2018-12-08 09:01:38 +08:00
}
}
.topic-header-extra {
display: inline-flex;
align-items: center;
max-width: 100%;
gap: 0.5em;
.discourse-tags {
display: inline;
color: var(--header_primary-high);
@include ellipsis;
.discourse-tag {
display: inline; // tags need to stay inline in order for them to truncate
vertical-align: unset;
}
}
}
}
// PM header participants
$avatar-height: 1.641em;
$mobile-avatar-height: 1.532em;
.topic-header-participants {
display: flex;
align-items: center;
font-size: var(--font-down-1);
@include ellipsis;
&:not(:first-child) {
margin-left: 5px;
}
.trigger-user-card,
.trigger-group-card {
&:not(:last-of-type) {
margin-right: 5px;
}
}
.trigger-user-card {
.icon {
height: $avatar-height;
.mobile-view & {
height: $mobile-avatar-height;
}
display: inline-block;
img {
height: 100%;
width: auto;
}
}
}
.trigger-group-card {
padding: 0 5px;
border: 1px solid var(--primary-low);
border-radius: 0.25em;
min-width: 3em;
@include ellipsis;
.icon {
display: flex;
align-items: center;
height: $avatar-height;
.mobile-view & {
height: $mobile-avatar-height;
}
color: var(--primary-high);
.d-icon {
margin-right: 5px;
}
}
span {
@include ellipsis;
}
}
.more-participants {
color: var(--header_primary-high);
margin-left: 5px;
}
}
.d-header-mode {
.bootstrap-mode {
color: var(--primary-medium);
font-size: var(--font-down-1);
margin-left: 1em;
padding: 0.15em 0.5em;
&:focus {
background-color: var(--primary-medium);
color: var(--secondary);
}
}
.fk-d-button-tooltip .fk-d-tooltip__trigger {
color: var(--header_primary-high);
background: transparent;
}
}
DEV: Convert header to glimmer (#25214) Here is a breakdown of the changes that will be implemented in this PR. # Widgets -> Glimmer Obviously, the intention of the todo here is to convert the header from widgets to glimmer. This PR splits the respective widgets as so: ### widgets/site-header.js ```mermaid height=200 flowchart TB A[widgets/site-header.js] A-->B[components/glimmer-site-header.gjs] ``` ### widgets/header.js and children ```mermaid height=200 flowchart TB A[widgets/header.js] A-->B[components/glimmer-header.gjs] B-->C[glimmer-header/contents.gjs] C-->D[./auth-buttons.gjs] C-->E[./icons.gjs] C-->F[./user-menu-wrapper.gjs] C-->G[./hamburger-dropdown-wrapper.gjs] C-->H[./user-menu-wrapper.gjs] C-->I[./sidebar-toggle.gjs] C-->J[./topic/info.gjs] ``` There are additional components rendered within the `glimmer-header/*` components, but I will leave those out for now. From this view you can see that we split apart the logic of `widgets/header.js` into 10+ components. Breaking apart these mega files has many benefits (readability, etc). # Services I have introduced a [header](https://github.com/discourse/discourse/blob/cdb42caa04ebcd1cf395dbe0cea96a13ce007099/app/assets/javascripts/discourse/app/services/header.js) service. This simplifies how we pass around data in the header, as well as fixes a bug we have with "swiping" menu panels. # Modifiers Added a [close-on-click-outside](https://github.com/discourse/discourse/blob/cdb42caa04ebcd1cf395dbe0cea96a13ce007099/app/assets/javascripts/discourse/app/modifiers/close-on-click-outside.js) modifier that is built upon the [close-on-click-outside modifier](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/float-kit/addon/modifiers/close-on-click-outside.js) that @jjaffeux built for float-kit. I think we could replace float-kit's implementation with mine and have it in a centralized location as they are extremely similar. # Tests Rewrote the existing header tests ([1](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/tests/integration/components/widgets/header-test.js), [2](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/tests/integration/components/site-header-test.js)) as system tests. # Other - Converted `widgets/user-status-bubble.js` to a gjs component - Converted `widgets/sidebar-toggle.js` to a gjs component - Converted `topicFeaturedLinkNode()` to a gjs component - Deprecated the [docking mixin](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/mixins/docking.js)
2024-02-24 02:08:15 +08:00
#additional-panel-wrapper {
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;
border-radius: var(--d-border-radius-large);
overflow: auto;
}