You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
2.4 KiB
Vue
130 lines
2.4 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref } from 'vue'
|
|
import type { DefaultTheme } from 'vitepress'
|
|
|
|
import Tree from './Tree.vue'
|
|
import VPLink from 'vitepress/dist/client/theme-default/components/VPLink.vue'
|
|
|
|
const props = defineProps<{
|
|
item: DefaultTheme.SidebarItem
|
|
}>()
|
|
const isOpen = ref<boolean>(false)
|
|
const isFolder = computed<boolean>(() => {
|
|
return !!(props.item.items && props.item.items.length)
|
|
})
|
|
|
|
const toggle = function () {
|
|
if (isFolder.value) {
|
|
isOpen.value = !isOpen.value
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<li
|
|
class="item"
|
|
:class="{
|
|
folder: isFolder,
|
|
opened: isOpen,
|
|
'is-link': !!props.item.link
|
|
}"
|
|
>
|
|
<span
|
|
class="title"
|
|
@click="toggle"
|
|
>
|
|
<div
|
|
v-if="isFolder"
|
|
class="icon"
|
|
>
|
|
<svg
|
|
viewBox="0 -0.5 17 17"
|
|
version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
>
|
|
<path d="M6.113,15.495 C5.531,16.076 4.01,16.395 4.01,14.494 L4.01,1.506 C4.01,-0.333 5.531,-0.076 6.113,0.506 L12.557,6.948 C13.137,7.529 13.137,8.47 12.557,9.052 L6.113,15.495 L6.113,15.495 Z"></path>
|
|
</svg>
|
|
</div>
|
|
<VPLink :href="props.item.link">
|
|
{{ props.item.text }}
|
|
</VPLink>
|
|
</span>
|
|
<Tree
|
|
v-show="isOpen"
|
|
v-if="isFolder"
|
|
:items="props.item.items"
|
|
class="list"
|
|
/>
|
|
</li>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.item {
|
|
position: relative;
|
|
margin-left: 5px;
|
|
}
|
|
|
|
.item:not(.folder) {
|
|
border-left: 1px dashed var(--vp-c-text-3);
|
|
}
|
|
|
|
.item:not(.folder)::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: calc(50% - .5px);
|
|
left: 3px;
|
|
width: 12px;
|
|
height: 0;
|
|
border-top: 1px dashed var(--vp-c-text-3);
|
|
}
|
|
|
|
.title {
|
|
position: relative;
|
|
padding-left: 20px;
|
|
}
|
|
|
|
.folder .title {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.icon {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 20px;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.icon svg {
|
|
position: relative;
|
|
margin-left: -3px;
|
|
width: 10px;
|
|
height: 10px;
|
|
fill: var(--vp-c-text-3);
|
|
transition: fill .25s;
|
|
}
|
|
|
|
.item:not(.is-link) > .title:hover > .icon svg,
|
|
.icon:hover svg {
|
|
fill: var(--vp-c-brand-1);
|
|
}
|
|
|
|
.opened > .title > .icon svg {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
:deep(.link) {
|
|
color: var(--vp-c-text-1);
|
|
text-decoration: none;
|
|
}
|
|
|
|
:deep(.link:hover) {
|
|
color: var(--vp-c-brand-1);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.item :deep(.list) {
|
|
padding-left: 20px;
|
|
}
|
|
</style> |