You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pages/components/header.js

121 lines
3.2 KiB
JavaScript

export class Header extends HTMLElement {
icons = {
menu: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-list" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
</svg>`,
dot: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
<path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/>
</svg>`,
}
constructor() {
super()
this.attachShadow({mode: 'open'})
this.addButton(this.icons.menu, () => {
this.menu.pages = this.getPages()
this.menuPanel.classList.add('open')
this.overlay.classList.add('open')
})
this.addDivider()
this.addButton(this.icons.dot)
this.addMenu()
}
addButton(html, onClick) {
const b = document.createElement('button')
b.innerHTML = html
this.shadowRoot.appendChild(b)
if (onClick) {
b.addEventListener('click', onClick)
}
}
addDivider() {
const d = document.createElement('div')
d.classList.add('divider')
this.shadowRoot.appendChild(d)
}
addMenu() {
this.overlay = document.createElement('div')
this.overlay.classList.add('overlay')
this.shadowRoot.appendChild(this.overlay)
this.menuPanel = document.createElement('div')
this.menuPanel.classList.add('menu')
this.menu = document.createElement('m-nav-menu')
this.menuPanel.appendChild(this.menu)
this.shadowRoot.appendChild(this.menuPanel)
this.overlay.addEventListener('click', () => {
this.close()
})
this.menu.addEventListener('close', () => {
this.close()
})
}
close() {
this.overlay.classList.add('closing')
this.overlay.classList.remove('open')
this.menuPanel.classList.remove('open')
setTimeout(() => {
this.overlay.classList.remove('closing')
}, 250)
}
connectedCallback() {
const style = document.createElement('style')
style.textContent = `
:host {
width: 100%;
background: #111;
color: #ddd;
display: flex;
flex-direction: row;
}
button {
border: none;
background: inherit;
color: inherit;
font-size: 24px;
width: 30px;
}
div.divider {
flex-grow: 1;
}
div.menu {
position: fixed;
top: 0;
left: -90vw;
height: 100vh;
width: 90vw;
background-color: #fff;
transition: left .25s ease-in-out;
}
div.menu.open {
left: 0;
}
div.overlay {
position: fixed;
top: 0;
left: -100vw;
height: 100vh;
width: 100vw;
opacity: 0%;
transition: opacity .25s ease-in;
background: #777;
}
div.overlay.closing {
left: 0;
}
div.overlay.open {
left: 0;
opacity: 15%;
}
`
this.shadowRoot.append(style)
}
getPages() {
return Object.keys(localStorage).slice().sort()
}
}