/**
* Site Header Component
* Sticky header container that holds top-bar, navigation, and search
* Collapses on scroll down, expands on scroll up
* Based on: https://stackoverflow.com/questions/63902512/
*/
class SiteHeader extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
this.prevScrollPos = 0;
this.headerOffset = 0;
this.collapsibleHeight = 0;
this.upwardScroll = 0;
this.handleScroll = this.handleScroll.bind(this);
}
connectedCallback() {
this.render();
this.collapsible = this.shadowRoot.querySelector(".collapsible");
window.addEventListener("scroll", this.handleScroll, { passive: true });
}
disconnectedCallback() {
window.removeEventListener("scroll", this.handleScroll);
}
handleScroll() {
const currentScrollPos = Math.max(0, window.scrollY);
const isScrollingDown = currentScrollPos > this.prevScrollPos;
const delta = currentScrollPos - this.prevScrollPos;
if (!this.collapsibleHeight && this.collapsible) {
this.collapsibleHeight = this.collapsible.scrollHeight;
}
if (isScrollingDown) {
this.upwardScroll = 0;
this.headerOffset = Math.min(
this.collapsibleHeight,
Math.max(0, this.headerOffset + delta)
);
this.classList.remove("reveal");
} else if (delta < 0) {
this.upwardScroll += Math.abs(delta);
if (this.upwardScroll >= 20) {
this.headerOffset = 0;
this.classList.add("reveal");
}
}
this.collapsible.style.transform = `translateY(-${this.headerOffset}px)`;
this.prevScrollPos = currentScrollPos;
}
render() {
this.shadowRoot.innerHTML = `
`;
}
}
customElements.define("site-header", SiteHeader);