-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
sidebar.ts
119 lines (98 loc) · 2.84 KB
/
sidebar.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import type { DefaultTheme } from 'vitepress/theme'
import { ensureStartingSlash } from './utils'
import { isActive } from '../../shared'
export interface SidebarLink {
text: string
link: string
docFooterText?: string
}
type SidebarItem = DefaultTheme.SidebarItem
/**
* 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
): SidebarItem[] {
if (Array.isArray(_sidebar)) return addBase(_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))
})
const sidebar = dir ? _sidebar[dir] : []
return Array.isArray(sidebar)
? addBase(sidebar)
: addBase(sidebar.items, sidebar.base)
}
/**
* Get or generate sidebar group from the given sidebar items.
*/
export function getSidebarGroups(sidebar: SidebarItem[]): SidebarItem[] {
const groups: 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: SidebarItem[]): SidebarLink[] {
const links: SidebarLink[] = []
function recursivelyExtractLinks(items: SidebarItem[]) {
for (const item of items) {
if (item.text && item.link) {
links.push({
text: item.text,
link: item.link,
docFooterText: item.docFooterText
})
}
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: SidebarItem | 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
}
function addBase(items: SidebarItem[], _base?: string): SidebarItem[] {
return [...items].map((_item) => {
const item = { ..._item }
const base = item.base || _base
if (base && item.link) item.link = base + item.link
if (item.items) item.items = addBase(item.items, base)
return item
})
}