|
|
|
|
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, 'nav', () => {
|
|
|
|
|
this.menu.pages = this.getPages()
|
|
|
|
|
this.menuPanel.classList.add('open')
|
|
|
|
|
this.overlay.classList.add('open')
|
|
|
|
|
})
|
|
|
|
|
this.addDivider()
|
|
|
|
|
this.addButton(this.icons.dot, 'page', () => {
|
|
|
|
|
this.pageMenuPanel.classList.add('open')
|
|
|
|
|
this.overlay.classList.add('open')
|
|
|
|
|
})
|
|
|
|
|
this.addMenu()
|
|
|
|
|
this.addPageMenu()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addButton(html, cls, onClick) {
|
|
|
|
|
const b = document.createElement('button')
|
|
|
|
|
b.innerHTML = html
|
|
|
|
|
b.classList.add(cls)
|
|
|
|
|
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()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addPageMenu() {
|
|
|
|
|
this.pageMenu = document.createElement('m-page-menu')
|
|
|
|
|
this.pageMenu.add('download', () => {
|
|
|
|
|
const text = localStorage.getItem(this.path)
|
|
|
|
|
const sp = this.path.split('/')
|
|
|
|
|
const filename = sp[sp.length - 1]
|
|
|
|
|
const el = document.createElement('a')
|
|
|
|
|
el.setAttribute(
|
|
|
|
|
'href',
|
|
|
|
|
'data:text/plain;charset=utf-8,' +
|
|
|
|
|
encodeURIComponent(text)
|
|
|
|
|
)
|
|
|
|
|
el.setAttribute('download', filename)
|
|
|
|
|
el.style.display = 'none'
|
|
|
|
|
this.shadowRoot.appendChild(el)
|
|
|
|
|
el.click()
|
|
|
|
|
this.shadowRoot.removeChild(el)
|
|
|
|
|
})
|
|
|
|
|
this.pageMenu.addEventListener('close', () => {
|
|
|
|
|
this.close()
|
|
|
|
|
})
|
|
|
|
|
this.pageMenuPanel = document.createElement('div')
|
|
|
|
|
this.pageMenuPanel.appendChild(this.pageMenu)
|
|
|
|
|
this.pageMenuPanel.classList.add('page-menu')
|
|
|
|
|
this.shadowRoot.appendChild(this.pageMenuPanel)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
close() {
|
|
|
|
|
this.overlay.classList.add('closing')
|
|
|
|
|
this.overlay.classList.remove('open')
|
|
|
|
|
this.menuPanel.classList.remove('open')
|
|
|
|
|
this.pageMenuPanel.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%;
|
|
|
|
|
}
|
|
|
|
|
button.page {
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
div.page-menu {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 28px;
|
|
|
|
|
right: 0;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
div.page-menu.open {
|
|
|
|
|
display: block;
|
|
|
|
|
}
|
|
|
|
|
`
|
|
|
|
|
this.shadowRoot.append(style)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getPages() {
|
|
|
|
|
return Object.keys(localStorage).slice().sort()
|
|
|
|
|
}
|
|
|
|
|
}
|