const hamburgerMenu = document.createElement('template')
hamburgerMenu.innerHTML = `
`
class HamburgerMenu extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' }).append(hamburgerMenu.content.cloneNode(true))
this.resumeScrolling = this.resumeScrolling.bind(this)
this.open = this.open.bind(this)
this.close = this.close.bind(this)
this.sideNav = this.shadowRoot.querySelector('.side-nav')
this.backdrop = this.shadowRoot.querySelector('.backdrop')
this.isOpen = false
this.animeOptions = {
duration: 300,
easing: 'ease'
}
}
static get observedAttributes() {
return ['open'];
}
resumeScrolling() {
const scrollY = document.body.style.top;
window.scrollTo(0, parseInt(scrollY || '0') * -1);
setTimeout(() => {
document.body.style.overflow = 'auto';
document.body.style.top = 'initial'
}, 300);
}
open() {
if (this.isOpen) return
document.body.style.overflow = 'hidden';
document.body.style.top = `-${window.scrollY}px`
this.classList.remove('hide')
this.sideNav.classList.add('reveal')
this.backdrop.classList.remove('hide')
this.backdrop.animate([
{
opacity: 0
},
{
opacity: 1
},
],
this.animeOptions)
.onfinish = () => {
this.isOpen = true
this.setAttribute('open', '')
}
}
close() {
if (!this.isOpen) return
this.sideNav.classList.remove('reveal')
this.backdrop.animate([
{
opacity: 1
},
{
opacity: 0
},
],
this.animeOptions)
.onfinish = () => {
this.backdrop.classList.add('hide')
this.classList.add('hide')
this.isOpen = false
this.removeAttribute('open')
}
}
connectedCallback() {
this.backdrop.addEventListener('click', this.close)
const resizeObserver = new ResizeObserver(entries => {
if (window.innerWidth < 640 && this.isOpen) {
this.classList.remove('hide')
}
else {
this.classList.add('hide')
}
if (window.innerWidth > 640) {
this.classList.remove('hide')
}
});
resizeObserver.observe(this)
}
disconnectedCallback() {
this.backdrop.removeEventListener('click', this.close)
}
attributeChangedCallback(name, oldVal, newVal) {
if (name === 'open') {
if (this.hasAttribute('open')) {
this.open()
}
}
}
}
window.customElements.define('hamburger-menu', HamburgerMenu);