101 lines
2.4 KiB
Vue
Raw Permalink Normal View History

2026-05-31 13:21:13 +02:00
<!--
Table Of content
`mode` can be either 'all', 'onlyCurrentTree' or 'onlySiblings'
Usage:
<Toc columns='2' maxDepth='3' mode='onlySiblings'/>
-->
<script setup lang='ts'>
import type { TocItem } from '@slidev/types'
import { computed } from 'vue'
import { useSlideContext } from '../context'
import TocList from './TocList.vue'
const props = withDefaults(
defineProps<{
columns?: string | number
listClass?: string | string[]
start?: string | number
listStyle?: string | string[]
maxDepth?: string | number
minDepth?: string | number
mode?: 'all' | 'onlyCurrentTree' | 'onlySiblings'
}>(),
{
columns: 1,
listClass: '',
start: 1,
listStyle: '',
maxDepth: Number.POSITIVE_INFINITY,
minDepth: 1,
mode: 'all',
},
)
const { $slidev } = useSlideContext()
function filterTreeDepth(tree: TocItem[], level = 1): TocItem[] {
if (level > Number(props.maxDepth)) {
return []
}
else if (level < Number(props.minDepth)) {
const activeItem = tree.find((item: TocItem) => item.active || item.activeParent)
return activeItem ? filterTreeDepth(activeItem.children, level + 1) : []
}
return tree
.map((item: TocItem) => ({
...item,
children: filterTreeDepth(item.children, level + 1),
}))
}
function filterOnlyCurrentTree(tree: TocItem[]): TocItem[] {
return tree
.filter(
(item: TocItem) => item.active || item.activeParent || item.hasActiveParent,
)
.map((item: TocItem) => ({
...item,
children: filterOnlyCurrentTree(item.children),
}))
}
function filterOnlySiblings(tree: TocItem[]): TocItem[] {
const treehasActiveItem = tree.some(
(item: TocItem) => item.active || item.activeParent || item.hasActiveParent,
)
return tree
.filter(() => treehasActiveItem)
.map((item: TocItem) => ({
...item,
children: filterOnlySiblings(item.children),
}))
}
const toc = computed(() => {
const tree = $slidev?.nav.tocTree
if (!tree)
return []
let tocTree = filterTreeDepth(tree)
if (props.mode === 'onlyCurrentTree')
tocTree = filterOnlyCurrentTree(tocTree)
else if (props.mode === 'onlySiblings')
tocTree = filterOnlySiblings(tocTree)
return tocTree
})
</script>
<template>
<div class="slidev-toc" :style="`column-count:${columns}`">
<TocList
:level="1"
:start="start"
:list-style="listStyle"
:list="toc"
:list-class="listClass"
/>
</div>
</template>