sebin-reference/src/components/Navbar.vue
2021-04-26 19:22:26 +02:00

139 lines
2.4 KiB
Vue

<template>
<nav class="nav" :class="{ 'nav--fixed': isFixed }" ref="nav">
<ul class="nav__list flex flex--row flex--nowrap flex--center-v">
<template v-for="(item, id) in navlinks">
<li class="nav__item" :key="id" v-show="isNsfw(item.nsfw)">
<a class="nav__link" href="#" v-scroll-to="item.href">
{{ item.label }}
</a>
<div class="nav__underline"></div>
</li>
</template>
</ul>
</nav>
</template>
<script>
import throttle from "lodash/throttle";
import debounce from "lodash/debounce";
export default {
props: {
navlinks: Array,
},
data() {
return {
isFixed: false,
offsetTop: null,
};
},
methods: {
setOffsetTop() {
this.offsetTop = this.$el.offsetTop;
this.$el.style.height = `${this.$refs.nav.scrollHeight}px`;
},
checkIsFixed() {
this.isFixed = this.offsetTop < window.scrollY;
},
isNsfw(item) {
if (this.$parent.$parent.nsfw) {
return true;
} else {
return this.$parent.$parent.nsfw === item;
}
},
},
mounted() {
window.addEventListener(
"scroll",
throttle(() => {
if (!this.offsetTop) {
this.setOffsetTop();
}
this.checkIsFixed();
}, 50)
);
window.addEventListener(
"resize",
debounce(() => {
this.setOffsetTop();
this.checkIsFixed();
}, 100)
);
},
};
</script>
<style lang="scss">
@import "@scss/base.scss";
.nav {
&--fixed .nav__list {
background-color: $bg-color-light;
position: fixed;
top: 0;
left: 0;
right: 0;
}
}
.nav__list {
margin: 0;
padding: 0 0.5em;
list-style-type: none;
z-index: 1;
overflow: auto;
width: 100%;
@include mq-desktop {
justify-content: center;
}
}
.nav__item {
padding: 0.5em 0.375em;
white-space: nowrap;
}
.nav__link {
color: $copy-color;
display: block;
margin-bottom: 0.25em;
text-decoration: none;
&:hover ~ .nav__underline {
&::before,
&::after {
width: 50%;
}
}
}
.nav__underline {
position: relative;
display: block;
width: 100%;
&::before,
&::after {
content: "";
position: absolute;
width: 0;
height: 0.125em;
background-color: $copy-color;
bottom: 0;
transition: all 0.2s ease-in-out;
}
&::before {
left: 50%;
}
&::after {
right: 50%;
}
}
</style>