diff --git a/javascripts/discourse/components/sticky-sidebar.hbs b/javascripts/discourse/components/sticky-sidebar.hbs index b8105a5..4055ffe 100644 --- a/javascripts/discourse/components/sticky-sidebar.hbs +++ b/javascripts/discourse/components/sticky-sidebar.hbs @@ -2,14 +2,16 @@
{{yield}} diff --git a/javascripts/discourse/components/sticky-sidebar.js b/javascripts/discourse/components/sticky-sidebar.js index d9e4241..e8069af 100644 --- a/javascripts/discourse/components/sticky-sidebar.js +++ b/javascripts/discourse/components/sticky-sidebar.js @@ -7,10 +7,11 @@ export default class StickySidebar extends Component { @tracked bottom = 0; @tracked position = "relative"; + headerHeight = 72; offset = 0; prevScrollTop = 0; yOrigin = 0; - mode = "unset"; + mode = "top"; @action onScroll() { @@ -22,33 +23,49 @@ export default class StickySidebar extends Component { // save the initial vertical position this.yOrigin = getYOrigin(this.element); } - const stickyTop = this.yOrigin; if (scrollingUp) { - if (isTopInView(element, this.yOrigin)) { - this.mode = "top"; - this.position = "fixed"; - this.top = stickyTop; - this.bottom = "unset"; - } - if (this.mode === "bottom") { - this.mode = "between"; - const top = element.getBoundingClientRect().top; - this.position = "relative"; - this.top = top + scrollY - this.yOrigin; + switch (this.mode) { + case "between": + if (isTopInView(element, this.headerHeight)) { + this.mode = "pinned"; + this.position = "fixed"; + this.top = `${this.headerHeight}px`; + this.bottom = "unset"; + } + break; + case "pinned": + if (scrollY < this.yOrigin - this.headerHeight) { + this.mode = "top"; + this.position = "relative"; + this.top = 0; + this.bottom = "unset"; + } + break; + case "bottom": + this.mode = "between"; + const top = element.getBoundingClientRect().top; + this.position = "relative"; + this.top = top + scrollY - this.yOrigin + "px"; + break; } } else if (scrollingDown) { - if (isBottomInView(element, this.yOrigin)) { - this.mode = "bottom"; - this.position = "fixed"; - this.bottom = 0; - this.top = "unset"; - } - if (this.mode === "top") { - this.mode = "between"; - const top = element.getBoundingClientRect().top; - this.position = "relative"; - this.top = top + scrollY - this.yOrigin; + switch (this.mode) { + case "between": + if (isBottomInView(element, this.yOrigin)) { + this.mode = "bottom"; + this.position = "fixed"; + this.bottom = 0; + this.top = "unset"; + } + break; + case "pinned": + case "top": + this.mode = "between"; + const top = element.getBoundingClientRect().top; + this.position = "relative"; + this.top = top + scrollY - this.yOrigin; + break; } } this.prevScrollTop = scrollY; @@ -58,6 +75,10 @@ export default class StickySidebar extends Component { didInsert(element) { this.element = element; this.offset = this.element.offsetTop; + const headerElement = document.querySelector(".d-header"); + if (headerElement) { + this.headerHeight = headerElement.offsetHeight; + } } }