mirror of https://github.com/vuejs/vitepress
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.4 KiB
108 lines
2.4 KiB
import type { DefaultTheme } from 'vitepress/theme'
|
|
import { ensureStartingSlash, isActive } from './utils'
|
|
|
|
export interface SidebarLink {
|
|
text: string
|
|
link: string
|
|
}
|
|
|
|
/**
|
|
* Get the `Sidebar` from sidebar option. This method will ensure to get correct
|
|
* sidebar config from `MultiSideBarConfig` with various path combinations such
|
|
* as matching `guide/` and `/guide/`. If no matching config was found, it will
|
|
* return empty array.
|
|
*/
|
|
export function getSidebar(
|
|
sidebar: DefaultTheme.Sidebar | undefined,
|
|
path: string
|
|
): DefaultTheme.SidebarItem[] {
|
|
if (Array.isArray(sidebar)) {
|
|
return sidebar
|
|
}
|
|
|
|
if (sidebar == null) {
|
|
return []
|
|
}
|
|
|
|
path = ensureStartingSlash(path)
|
|
|
|
const dir = Object.keys(sidebar)
|
|
.sort((a, b) => {
|
|
return b.split('/').length - a.split('/').length
|
|
})
|
|
.find((dir) => {
|
|
// make sure the multi sidebar key starts with slash too
|
|
return path.startsWith(ensureStartingSlash(dir))
|
|
})
|
|
|
|
return dir ? sidebar[dir] : []
|
|
}
|
|
|
|
/**
|
|
* Get or generate sidebar group from the given sidebar items.
|
|
*/
|
|
export function getSidebarGroups(
|
|
sidebar: DefaultTheme.SidebarItem[]
|
|
): DefaultTheme.SidebarItem[] {
|
|
const groups: DefaultTheme.SidebarItem[] = []
|
|
|
|
let lastGroupIndex: number = 0
|
|
|
|
for (const index in sidebar) {
|
|
const item = sidebar[index]
|
|
|
|
if (item.items) {
|
|
lastGroupIndex = groups.push(item)
|
|
continue
|
|
}
|
|
|
|
if (!groups[lastGroupIndex]) {
|
|
groups.push({ items: [] })
|
|
}
|
|
|
|
groups[lastGroupIndex]!.items!.push(item)
|
|
}
|
|
|
|
return groups
|
|
}
|
|
|
|
export function getFlatSideBarLinks(
|
|
sidebar: DefaultTheme.SidebarItem[]
|
|
): SidebarLink[] {
|
|
const links: SidebarLink[] = []
|
|
|
|
function recursivelyExtractLinks(items: DefaultTheme.SidebarItem[]) {
|
|
for (const item of items) {
|
|
if (item.text && item.link) {
|
|
links.push({ text: item.text, link: item.link })
|
|
}
|
|
|
|
if (item.items) {
|
|
recursivelyExtractLinks(item.items)
|
|
}
|
|
}
|
|
}
|
|
|
|
recursivelyExtractLinks(sidebar)
|
|
|
|
return links
|
|
}
|
|
|
|
/**
|
|
* Check if the given sidebar item contains any active link.
|
|
*/
|
|
export function hasActiveLink(
|
|
path: string,
|
|
items: DefaultTheme.SidebarItem | DefaultTheme.SidebarItem[]
|
|
): boolean {
|
|
if (Array.isArray(items)) {
|
|
return items.some((item) => hasActiveLink(path, item))
|
|
}
|
|
|
|
return isActive(path, items.link)
|
|
? true
|
|
: items.items
|
|
? hasActiveLink(path, items.items)
|
|
: false
|
|
}
|