sphinx_nervproject_theme/ui/src/vuepress/Sidebar.vue

126 lines
2.4 KiB
Vue

<template>
<div class="sidebar">
<NavLinks/>
<slot name="top"/>
<ul class="sidebar-links" v-if="items.length">
<li v-for="(item, i) in items" :key="i">
<SidebarGroup
v-if="item.type === 'group'"
:item="item"
:first="i === 0"
:open="i === openGroupIndex"
:collapsable="item.collapsable"
@toggle="toggleGroup(i)"
/>
<SidebarLink v-else :item="item"/>
</li>
</ul>
<slot name="bottom"/>
</div>
</template>
<script>
import SidebarGroup from './SidebarGroup.vue'
import SidebarLink from './SidebarLink.vue'
import NavLinks from './NavLinks.vue'
import { isActive } from './util'
export default {
components: { SidebarGroup, SidebarLink, NavLinks },
props: ['items'],
data () {
return {
openGroupIndex: 0
}
},
created () {
this.refreshIndex()
},
watch: {
'$route' () {
this.refreshIndex()
}
},
methods: {
refreshIndex () {
const index = resolveOpenGroupIndex(
this.$route,
this.items
)
if (index > -1) {
this.openGroupIndex = index
}
},
toggleGroup (index) {
this.openGroupIndex = index === this.openGroupIndex ? -1 : index
},
isActive (page) {
return isActive(this.$route, page.path)
}
}
}
function resolveOpenGroupIndex (route, items) {
for (let i = 0; i < items.length; i++) {
const item = items[i]
if (item.type === 'group' && item.children.some(c => isActive(route, c.path))) {
return i
}
}
return -1
}
</script>
<style lang="less">
@import './styles/config.less';
.sidebar {
ul {
padding: 0;
margin: 0;
list-style-type: none;
}
a, a:visited {
display: inline-block;
}
.nav-links {
display: none;
border-bottom: 0.3em solid var(--SdBClr);
padding: 0.5rem 0 0.75rem 0;
a, a:visited {
font-weight: 600;
}
.nav-item, .repo-link {
display: block;
line-height: 1.25rem;
font-size: 1.1em;
padding: 0.5rem 0 0.5rem 1.5rem;
}
}
.sidebar-links {
padding: 1.5rem 0;
}
}
@media (max-width: @MQMobile) {
.sidebar {
.nav-links {
display: block;
.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active::after {
top: calc(1rem - 0.3em);
}
}
.sidebar-links {
padding: 1rem 0;
}
}
}
</style>