mirror of https://github.com/YunYouJun/valaxy
159 lines
3.1 KiB
Vue
159 lines
3.1 KiB
Vue
<script lang="ts" setup>
|
|
import { computed } from 'vue'
|
|
import { removeItemFromCategory, useCategories, usePageList, useSidebar } from 'valaxy'
|
|
import { useThemeConfig } from '../composables'
|
|
|
|
defineProps<{
|
|
open: boolean
|
|
}>()
|
|
|
|
const pages = usePageList()
|
|
const themeConfig = useThemeConfig()
|
|
|
|
const sidebar = computed(() => themeConfig.value.sidebar)
|
|
const categories = computed(() => {
|
|
const cs = useCategories('', pages.value)
|
|
const cList = cs.value
|
|
removeItemFromCategory(cList, 'Uncategorized')
|
|
|
|
const sidebar = themeConfig.value.sidebar
|
|
if (sidebar) {
|
|
cList.children.forEach((item) => {
|
|
if (!themeConfig.value.sidebar.includes(item.name))
|
|
removeItemFromCategory(cList, item.name)
|
|
})
|
|
}
|
|
return cList
|
|
})
|
|
|
|
function getCategoryByName(name: string) {
|
|
return categories.value.children.find(c => c.name === name)
|
|
}
|
|
|
|
const { hasSidebar } = useSidebar()
|
|
</script>
|
|
|
|
<template>
|
|
<aside
|
|
v-if="hasSidebar"
|
|
class="press-sidebar shadow-lg" :class="{ open }"
|
|
@click.stop
|
|
>
|
|
<div text="left" m="2">
|
|
<ul v-for="item in sidebar" :key="item" class="category-list">
|
|
<template v-if="typeof item === 'string'">
|
|
<PressCategory
|
|
v-if="getCategoryByName(item)"
|
|
:category="getCategoryByName(item)"
|
|
:collapsable="false"
|
|
/>
|
|
</template>
|
|
<PressSidebarItem
|
|
v-else
|
|
p="t-2"
|
|
border="t t-$pr-c-divider-light"
|
|
:item="item"
|
|
:depth="0"
|
|
/>
|
|
</ul>
|
|
</div>
|
|
</aside>
|
|
</template>
|
|
|
|
<style lang="scss">
|
|
@use 'valaxy/client/styles/mixins/index.scss' as *;
|
|
|
|
.press-sidebar {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
padding: 1rem;
|
|
top: var(--pr-nav-height);
|
|
z-index: var(--pr-z-sidebar);
|
|
width: calc(100vw - 64px);
|
|
max-width: 320px;
|
|
background-color: var(--va-c-bg);
|
|
opacity: 0;
|
|
overflow-x: hidden;
|
|
overflow-y: auto;
|
|
overflow-y: overlay;
|
|
transform: translateX(-100%);
|
|
transition: opacity 0.5s, transform 0.25s ease;
|
|
|
|
&.open {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
transition: opacity 0.25s,
|
|
transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
|
|
}
|
|
}
|
|
|
|
@include screen('md') {
|
|
.press-sidebar {
|
|
z-index: 1;
|
|
width: var(--va-sidebar-width);
|
|
max-width: 100%;
|
|
background-color: var(--va-c-bg-alt);
|
|
opacity: 1;
|
|
box-shadow: none;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
@include mobile {
|
|
.press-sidebar {
|
|
top: 0;
|
|
}
|
|
}
|
|
|
|
.category-list {
|
|
&:first-child {
|
|
.category-list-item {
|
|
border-top: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
.post-list-item {
|
|
a {
|
|
color: var(--va-c-text-light);
|
|
transition: all 0.2s;
|
|
|
|
&:hover {
|
|
color: var(--va-c-primary);
|
|
}
|
|
|
|
&.active {
|
|
color: var(--va-c-primary);
|
|
}
|
|
}
|
|
}
|
|
|
|
.press-sidebar-item {
|
|
.caret {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin-right: -7px;
|
|
width: 32px;
|
|
height: 32px;
|
|
color: var(--vp-c-text-3);
|
|
cursor: pointer;
|
|
transition: color 0.25s;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
&:hover .caret {
|
|
color: var(--vp-c-text-2);
|
|
}
|
|
|
|
&:hover .caret:hover {
|
|
color: var(--vp-c-text-1);
|
|
}
|
|
}
|
|
|
|
.category-list+.category-list {
|
|
margin-top: 1rem;
|
|
}
|
|
</style>
|