work.suroh.tk/_includes/components/nav-primary.webc

134 lines
2.9 KiB
Plaintext
Raw Normal View History

<nav id="primary">
<nav-link link="/" data-name="~"><~</nav-link>
<nav-link webc:for="c in categories" :category="c" :data-name="c"></nav-link>
<button class="audioToggle"></button>
</nav>
<nav id="sub" slot="subnav">
<ul webc:for="(c, pages) in categories" :data-name="c">
<li webc:for="p of pages">
<a :href="p.url" @text="p.data.title || p.fileSlug"></a>
</li>
</ul>
</nav>
<section style="position: fixed; bottom: 0; left: 0; margin: 0; padding: 0; width: 100vw; height: 0px; overflow: visible; z-index: 100;mix-blend-mode: difference;">
<h1 id="menuItem"></h1>
</section>
<nav id="toTop">
<span>top</span>
</nav>
<script type="module">
class NavPrimary extends HTMLElement {
categories = []
subs = []
connectedCallback() {
this.categories = this.querySelectorAll('nav-link')
this.subs = this.querySelectorAll('ul')
this.activate()
window.addEventListener('popstate', (evt) => {
this.activate()
})
this.categories.forEach(n => {
n.addEventListener('click',() => {
const category = n.attributes.getNamedItem('category')
const link = n.attributes.getNamedItem('link')
if (link) {
history.pushState({}, '', link.value)
location.pathname = link.value
} else if (category) {
location.hash = category.value
}
})
})
}
activate() {
this.categories.forEach(i => {
const { value } = i.attributes.getNamedItem('category') || i.attributes.getNamedItem('link')
if (value != '/' && (value == location.hash.replace('#', '') || value == location.pathname)) {
i.classList.add('active')
} else {
i.classList.remove('active')
}
})
this.subs.forEach(s => {
const { name } = s.dataset
if (name == location.hash.replace('#', '') || name == location.pathname) {
s.classList.add('active')
} else {
s.classList.remove('active')
}
})
}
}
customElements.define('nav-primary', NavPrimary)
</script>
<style webc:scoped>
/* => CONTAINER */
nav {
display: flex;
margin: 1em var(--page-margin-inline) 0.5em;
font-size: 1.5em;
}
/* => LINKS */
nav-link {
padding-inline: 0.125em;
}
/* => AUDIO TOGGLE */
.audioToggle {
background: none;
border: none;
margin-inline-start: auto;
transition: color ease-in-out 0.1s;
}
.audioToggle:hover {
color: #CECECE;
cursor: pointer;
transition: color ease-in-out 0.1s;
}
.audioToggle::after {
content: '🔇'
}
.audioToggle.active::after {
content: '🔉'
}
/* => SUb NAV */
#sub {
display: grid;
grid-template: 1fr / 1fr;
}
#sub > ul {
grid-row: 1 / span 1;
grid-column: 1 / span 1;
max-height: 0px;
overflow: hidden;
transition: max-height 0.5s cubic-bezier(.22,.61,.36,1);
}
ul.active {
max-height: 50vh !important;
}
</style>