UX: Proper width of unsaved site setting banner (#32137)

Elements with position: fixed are taken out of the rendering context, so we can't easily make the banner the width of the main container using CSS. We tried a CSS hack, but that doesn't scale to larger screens, and probably breaks in some themes.

This is a simple JavaScript implementation that matches the width of the main container.
This commit is contained in:
Ted Johansson
2025-04-03 17:35:01 +08:00
committed by GitHub
parent a62c2b9a17
commit 6a6c0bc179
2 changed files with 32 additions and 9 deletions
@@ -1,6 +1,8 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import htmlSafe from "discourse/helpers/html-safe";
@@ -10,6 +12,7 @@ export default class AdminSiteSettingsChangesBanner extends Component {
@service siteSettingChangeTracker;
@tracked isSaving = false;
_resizer = null;
@action
async save() {
@@ -27,6 +30,29 @@ export default class AdminSiteSettingsChangesBanner extends Component {
this.siteSettingChangeTracker.discard();
}
@action
setupResizeObserver(element) {
const container = document.getElementById("main-container");
this._resizer = () => this.positionBanner(container, element);
this._resizer();
this._resizeObserver = window.addEventListener("resize", this._resizer);
}
@action
teardownResizeObserver() {
window.removeEventListener("resize", this._resizer);
}
positionBanner(container, element) {
if (container) {
const { width } = container.getBoundingClientRect();
element.style.width = `${width}px`;
}
}
get dirtyCount() {
return this.siteSettingChangeTracker.count;
}
@@ -55,7 +81,11 @@ export default class AdminSiteSettingsChangesBanner extends Component {
<template>
{{#if this.showBanner}}
<div class="admin-site-settings__changes-banner">
<div
class="admin-site-settings__changes-banner"
{{didInsert this.setupResizeObserver}}
{{willDestroy this.teardownResizeObserver}}
>
<span>{{htmlSafe this.bannerLabel}}</span>
<div class="controls">
<DButton
@@ -21,23 +21,17 @@
}
.admin-site-settings__changes-banner {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
bottom: 0;
padding: var(--space-6) var(--space-3);
max-width: var(--d-max-width);
width: calc(100% - (var(--d-sidebar-width) + 70px));
background-color: var(--secondary);
border-top: 2px solid var(--tertiary);
.has-sidebar-page & {
left: calc(var(--d-sidebar-width) + 70px);
}
@include breakpoint("mobile-extra-large") {
width: 100%;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
@@ -50,7 +44,6 @@
@include breakpoint("mobile-extra-large") {
flex-direction: column;
width: 90%;
}
}