From 22f700d7a3fc817e62571476d0680b8fc9f1e698 Mon Sep 17 00:00:00 2001
From: Bryce Huhtala <100382978+sketchius@users.noreply.github.com>
Date: Mon, 1 Jul 2024 09:06:10 +0200
Subject: [PATCH] FIX: Issue with sticky behavior (#19)
---
.../discourse/components/sticky-sidebar.hbs | 18 ++---
.../discourse/components/sticky-sidebar.js | 69 ++++++++++++-------
2 files changed, 55 insertions(+), 32 deletions(-)
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;
+ }
}
}