mirror of https://github.com/vuejs/vitepress
feat(theme): support dynamic headers and nesting in outline (#1281)
Co-authored-by: fi3ework <fi3ework@gmail.com>pull/1290/head
parent
8d6a20d665
commit
288aa48b92
@ -0,0 +1,166 @@
|
|||||||
|
import { describe, test, expect } from 'vitest'
|
||||||
|
import * as outline from 'client/theme-default/composables/outline'
|
||||||
|
|
||||||
|
describe('client/theme-default/composables/outline', () => {
|
||||||
|
describe('resolveHeader', () => {
|
||||||
|
test('levels range', () => {
|
||||||
|
expect(
|
||||||
|
outline.resolveHeaders(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
title: 'h2 - 1',
|
||||||
|
link: '#h2-1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 1',
|
||||||
|
link: '#h3-1'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[2, 3]
|
||||||
|
)
|
||||||
|
).toEqual([
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
title: 'h2 - 1',
|
||||||
|
link: '#h2-1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 1',
|
||||||
|
link: '#h3-1'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('specific level', () => {
|
||||||
|
expect(
|
||||||
|
outline.resolveHeaders(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
title: 'h2 - 1',
|
||||||
|
link: '#h2-1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 1',
|
||||||
|
link: '#h3-1'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
2
|
||||||
|
)
|
||||||
|
).toEqual([
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
title: 'h2 - 1',
|
||||||
|
link: '#h2-1'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('complex deep', () => {
|
||||||
|
expect(
|
||||||
|
outline.resolveHeaders(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
title: 'h2 - 1',
|
||||||
|
link: '#h2-1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 1',
|
||||||
|
link: '#h3-1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 4,
|
||||||
|
title: 'h4 - 1',
|
||||||
|
link: '#h4-1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 2',
|
||||||
|
link: '#h3-2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 4,
|
||||||
|
title: 'h4 - 2',
|
||||||
|
link: '#h4-2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
title: 'h2 - 2',
|
||||||
|
link: '#h2-2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 3',
|
||||||
|
link: '#h3-3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 4,
|
||||||
|
title: 'h4 - 3',
|
||||||
|
link: '#h4-3'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'deep'
|
||||||
|
)
|
||||||
|
).toEqual([
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
title: 'h2 - 1',
|
||||||
|
link: '#h2-1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 1',
|
||||||
|
link: '#h3-1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
level: 4,
|
||||||
|
title: 'h4 - 1',
|
||||||
|
link: '#h4-1'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 2',
|
||||||
|
link: '#h3-2',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
level: 4,
|
||||||
|
title: 'h4 - 2',
|
||||||
|
link: '#h4-2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
title: 'h2 - 2',
|
||||||
|
link: '#h2-2',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
title: 'h3 - 3',
|
||||||
|
link: '#h3-3',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
level: 4,
|
||||||
|
title: 'h4 - 3',
|
||||||
|
link: '#h4-3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -0,0 +1,51 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { MenuItem } from '../composables/outline.js'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
headers: MenuItem[]
|
||||||
|
onClick: (e: MouseEvent) => void
|
||||||
|
root?: boolean
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ul :class="root ? 'root' : 'nested'">
|
||||||
|
<li v-for="{ children, link, title } in headers">
|
||||||
|
<a class="outline-link" :href="link" @click="onClick">{{ title }}</a>
|
||||||
|
<template v-if="children?.length">
|
||||||
|
<VPDocAsideOutlineItem :headers="children" :onClick="onClick" />
|
||||||
|
</template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.root {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nested {
|
||||||
|
padding-left: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outline-link {
|
||||||
|
display: block;
|
||||||
|
line-height: 28px;
|
||||||
|
color: var(--vp-c-text-2);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
transition: color 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outline-link:hover,
|
||||||
|
.outline-link.active {
|
||||||
|
color: var(--vp-c-text-1);
|
||||||
|
transition: color 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outline-link.nested {
|
||||||
|
padding-left: 13px;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in new issue