This commit is contained in:
Fedor Katurov 2022-11-02 11:58:45 +06:00
commit 5104c2518b
34 changed files with 6844 additions and 0 deletions

View file

@ -0,0 +1,26 @@
<template>
<footer :class="[$style.footer, $attrs.class]">
<div>btw, have a nice day</div>
<div :class="$style.filler" />
<div>
(2018 - {{ new Date().getFullYear() }})
<NuxtLink to="https://github.com/muerwre/" target="_blank"
>muerwre</NuxtLink
>
</div>
</footer>
</template>
<style lang="scss" module>
.footer {
color: var(--color-text-secondary);
font-size: 0.8rem;
display: flex;
flex-direction: row;
width: 100%;
}
.filler {
flex: 1;
}
</style>

View file

@ -0,0 +1,36 @@
<template>
<nav>
<div :class="$style.section_title">Reference</div>
<div v-for="item in parentItems" key="item._path" :class="$style.row">
<LayoutMainMenuRow
:title="item.title"
:url="item._path"
:children="item.children"
/>
</div>
</nav>
</template>
<script setup>
const { data: navigation } = await useAsyncData("navigation", () => {
return fetchContentNavigation();
});
const parentItems = navigation.value.filter(
(it) => it.children && Array.isArray(it.children) && it.children.length > 0
);
</script>
<style lang="scss" module>
.section_title {
font-family: var(--family-roboto-slab);
font-weight: 600;
margin: 2rem 0 1.5rem;
font-size: 1.6rem;
}
.row {
margin-bottom: 15px;
}
</style>

View file

@ -0,0 +1,158 @@
<template>
<div
v-if="children?.length || !url"
:class="[$style.container, { [$style.secondary]: secondary }]"
>
<div :class="$style.heading">
{{ title }}
</div>
<div :class="$style.children">
<LayoutMainMenuRow
v-for="item in children"
key="item._path"
:title="item.title"
:url="item._path"
:children="item.children"
secondary
/>
</div>
</div>
<div v-else :class="$style.row">
<NuxtLink :to="url" :class="$style.link" :exactActiveClass="$style.active"
>{{ title }}
</NuxtLink>
</div>
</template>
<script lang="ts" setup>
interface Props {
title: string;
url?: string;
children?: Child[];
secondary?: boolean;
}
interface Child {
title: string;
_path: string;
children: Child[];
}
defineProps<Props>();
</script>
<script lang="ts">
export default defineComponent({
mounted() {
const active = document.querySelector(
`.${this.$style.link}.${this.$style.active}`
);
if (!active) return;
active?.scrollIntoView({ block: "center" });
},
});
</script>
<style lang="scss" module>
@mixin tree {
&::before {
content: " ";
background-color: var(--color-menu-line);
width: 10px;
height: 1px;
position: absolute;
top: 0.6em;
left: -17px;
}
}
.container {
position: relative;
&.secondary {
padding: 7px 2px 0;
&::before {
content: " ";
background-color: var(--color-menu-line);
width: 1px;
position: absolute;
top: -22px;
bottom: 13px;
left: -16px;
}
&:first-child::before {
top: -4px;
}
&:last-child::before {
bottom: auto;
height: 40px;
}
}
}
.row {
padding: 3px 2px;
position: relative;
&::before {
content: " ";
background-color: var(--color-menu-line);
width: 1px;
position: absolute;
top: -14px;
bottom: 13px;
left: -16px;
}
&:first-child::before {
top: -4px;
}
&:last-child::before {
bottom: auto;
height: 30px;
}
&:only-child::before {
height: 19px;
}
}
.heading {
font-weight: 600;
display: flex;
align-items: center;
text-transform: uppercase;
position: relative;
color: var(--color-menu-title);
.secondary & {
@include tree;
}
}
.link {
color: var(--color-menu-link);
text-decoration: none;
line-height: 1.4em;
position: relative;
@include tree;
&.active {
color: var(--color-menu-link-active);
font-weight: bold;
}
}
.children {
padding: 0 0 0 16px;
margin: 10px 3px;
position: relative;
}
</style>

View file

@ -0,0 +1,67 @@
<template>
<button :class="[$attrs.class, $style.button]">
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 0 24 24"
width="24"
fill="#ffffff"
:class="[$style.hamburger, { [$style.active]: active }]"
>
<rect x="0" y="3" width="24" height="2" />
<rect x="0" y="11" width="24" height="2" />
<rect x="0" y="19" width="24" height="2" />
</svg>
</button>
</template>
<script lang="ts" setup>
interface Props {
active?: boolean;
}
defineProps<Props>();
</script>
<style lang="scss" module>
.button {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
}
.hamburger {
fill: var(--color-text);
cursor: pointer;
transition: all 250ms;
&:hover {
fill: var(--color-link);
}
& > rect {
transition: transform 250ms;
}
&.active {
& > rect:nth-child(1) {
transform: rotate(45deg);
transform-origin: 2px 8px;
}
& > rect:nth-child(2) {
transform: scaleX(0);
transform-origin: 13px 0;
transition-delay: 100ms;
}
& > rect:nth-child(3) {
transform: rotate(-45deg);
transform-origin: 3px 16px;
transition-delay: 50ms;
}
}
}
</style>

View file

@ -0,0 +1,52 @@
<template>
<button
@click="toggleTheme"
:class="[$attrs.class, $style.button, { [$style.visible]: visible }]"
>
<ClientOnly>
<IconsMoon fill="currentColor" width="32" height="32" v-if="isDark" />
<IconsSun fill="currentColor" width="32" height="32" v-if="!isDark" />
</ClientOnly>
</button>
</template>
<script lang="ts" setup>
const visible = ref(false);
onMounted(() => {
visible.value = true;
});
</script>
<script lang="ts">
export default defineComponent({
methods: {
toggleTheme() {
this.$colorMode.preference =
this.$colorMode.preference === "dark" ? "light" : "dark";
},
},
computed: {
isDark() {
return this.$colorMode.preference === "dark";
},
},
});
</script>
<style lang="scss" module>
.button {
color: var(--color-text-secondary);
cursor: pointer;
transform: scale(0) rotate(180deg);
transition: all 0.25s ease-out;
&.visible {
transform: scale(1) rotate(0);
}
&:hover {
color: var(--color-text);
}
}
</style>