返回 slidev
Toc.vue
根目录 / packages / client / builtin / Toc.vue
1 <!--
2 Table Of content
3
4 `mode` can be either 'all', 'onlyCurrentTree' or 'onlySiblings'
5
6 Usage:
7
8 <Toc columns='2' maxDepth='3' mode='onlySiblings'/>
9 -->
10 <script setup lang='ts'>
11 import type { TocItem } from '@slidev/types'
12 import { computed } from 'vue'
13 import { useSlideContext } from '../context'
14 import TocList from './TocList.vue'
15
16 const props = withDefaults(
17 defineProps<{
18 columns?: string | number
19 listClass?: string | string[]
20 start?: string | number
21 listStyle?: string | string[]
22 maxDepth?: string | number
23 minDepth?: string | number
24 mode?: 'all' | 'onlyCurrentTree' | 'onlySiblings'
25 }>(),
26 {
27 columns: 1,
28 listClass: '',
29 start: 1,
30 listStyle: '',
31 maxDepth: Number.POSITIVE_INFINITY,
32 minDepth: 1,
33 mode: 'all',
34 },
35 )
36
37 const { $slidev } = useSlideContext()
38
39 function filterTreeDepth(tree: TocItem[], level = 1): TocItem[] {
40 if (level > Number(props.maxDepth)) {
41 return []
42 }
43 else if (level < Number(props.minDepth)) {
44 const activeItem = tree.find((item: TocItem) => item.active || item.activeParent)
45 return activeItem ? filterTreeDepth(activeItem.children, level + 1) : []
46 }
47 return tree
48 .map((item: TocItem) => ({
49 ...item,
50 children: filterTreeDepth(item.children, level + 1),
51 }))
52 }
53
54 function filterOnlyCurrentTree(tree: TocItem[]): TocItem[] {
55 return tree
56 .filter(
57 (item: TocItem) => item.active || item.activeParent || item.hasActiveParent,
58 )
59 .map((item: TocItem) => ({
60 ...item,
61 children: filterOnlyCurrentTree(item.children),
62 }))
63 }
64
65 function filterOnlySiblings(tree: TocItem[]): TocItem[] {
66 const treehasActiveItem = tree.some(
67 (item: TocItem) => item.active || item.activeParent || item.hasActiveParent,
68 )
69 return tree
70 .filter(() => treehasActiveItem)
71 .map((item: TocItem) => ({
72 ...item,
73 children: filterOnlySiblings(item.children),
74 }))
75 }
76
77 const toc = computed(() => {
78 const tree = $slidev?.nav.tocTree
79 if (!tree)
80 return []
81 let tocTree = filterTreeDepth(tree)
82 if (props.mode === 'onlyCurrentTree')
83 tocTree = filterOnlyCurrentTree(tocTree)
84 else if (props.mode === 'onlySiblings')
85 tocTree = filterOnlySiblings(tocTree)
86 return tocTree
87 })
88 </script>
89
90 <template>
91 <div class="slidev-toc" :style="`column-count:${columns}`">
92 <TocList
93 :level="1"
94 :start="start"
95 :list-style="listStyle"
96 :list="toc"
97 :list-class="listClass"
98 />
99 </div>
100 </template>
101
101 lines Plain Text