Skip to content

Commit 1964709

Browse files
committed
feat: support nesting in sidebar
1 parent 11c6528 commit 1964709

File tree

7 files changed

+254
-217
lines changed

7 files changed

+254
-217
lines changed

lib/default-theme/Layout.vue

+4-31
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
11
<template>
22
<div class="theme-container">
3-
<div class="sidebar">
4-
<ul>
5-
<li v-for="item in sidebarItems">
6-
<router-link v-if="item.type === 'page'" :to="item.path">
7-
{{ item.title || item.path }}
8-
</router-link>
9-
<div class="sidebar-group" v-else-if="item.type === 'heading'">
10-
<p class="sidebar-heading">{{ item.title }}</p>
11-
<ul>
12-
<li v-for="child in item.children">
13-
<router-link v-if="child.type === 'page'" :to="child.path">
14-
{{ child.title || child.path }}
15-
</router-link>
16-
</li>
17-
</ul>
18-
</div>
19-
</li>
20-
</ul>
21-
</div>
3+
<SideBar/>
224
<Index v-if="$page.path === '/index'" />
235
<Page v-else />
246
</div>
@@ -28,18 +10,10 @@
2810
import nprogress from 'nprogress'
2911
import Index from './Index.vue'
3012
import Page from './Page.vue'
31-
import resolveSidebar from './resolveSidebar'
13+
import SideBar from './SideBar.vue'
3214
3315
export default {
34-
components: { Index, Page },
35-
computed: {
36-
sidebarItems () {
37-
return resolveSidebar(
38-
this.$route,
39-
this.$site
40-
)
41-
}
42-
},
16+
components: { Index, Page, SideBar },
4317
mounted () {
4418
nprogress.configure({ showSpinner: false })
4519
@@ -57,6 +31,5 @@ export default {
5731
}
5832
</script>
5933

60-
<style src="./nprogress.css"></style>
6134
<style src="prismjs/themes/prism-tomorrow.css"></style>
62-
<style src="./theme.stylus" lang="stylus"></style>
35+
<style src="./styles/theme.stylus" lang="stylus"></style>

lib/default-theme/SideBar.vue

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<template>
2+
<div class="sidebar">
3+
<ul>
4+
<li v-for="(item, i) in sidebarItems">
5+
<router-link v-if="item.type === 'page'" :to="item.path">
6+
{{ item.title || item.path }}
7+
</router-link>
8+
<div v-else-if="item.type === 'heading'"
9+
class="sidebar-group"
10+
:class="{ first: i === 0 }">
11+
<p class="sidebar-heading">{{ item.title }}</p>
12+
<ul>
13+
<li v-for="child in item.children">
14+
<router-link v-if="child.type === 'page'" :to="child.path">
15+
{{ child.title || child.path }}
16+
</router-link>
17+
</li>
18+
</ul>
19+
</div>
20+
</li>
21+
</ul>
22+
</div>
23+
</template>
24+
25+
<script>
26+
function resolveSidebar (route, site) {
27+
const { pages, themeConfig } = site
28+
const sidebarConfig = themeConfig.sidebar
29+
if (!sidebarConfig) {
30+
return pages
31+
} else {
32+
const matchingConfig = Array.isArray(sidebarConfig)
33+
? sidebarConfig
34+
: resolveMatchingSidebar(route, sidebarConfig)
35+
return matchingConfig.map(item => resolveItem(item, site.pages))
36+
}
37+
}
38+
39+
function resolveMatchingSidebar (route, sidebarConfig) {
40+
for (const base in sidebarConfig) {
41+
if (ensureEndingSlash(route.path).indexOf(base) === 0) {
42+
return sidebarConfig[base]
43+
}
44+
}
45+
}
46+
47+
function ensureEndingSlash (path) {
48+
return /(\.html|\/)$/.test(path)
49+
? path
50+
: path + '/'
51+
}
52+
53+
function resolveItem (item, pages) {
54+
if (typeof item === 'string') {
55+
return resolvePage(pages, item)
56+
} else if (Array.isArray(item)) {
57+
return Object.assign(resolvePage(pages, item[0]), {
58+
title: item[1]
59+
})
60+
} else {
61+
const children = item.children || []
62+
return {
63+
type: 'heading',
64+
title: item.title,
65+
children: children.map(child => resolveItem(child, pages)),
66+
collapsable: children.length && item.collapsable
67+
}
68+
}
69+
}
70+
71+
function resolvePage (pages, rawPath) {
72+
const path = normalize(rawPath)
73+
for (let i = 0; i < pages.length; i++) {
74+
if (normalize(pages[i].path) === path) {
75+
return Object.assign({}, pages[i], {
76+
type: 'page',
77+
path: ensureExt(rawPath)
78+
})
79+
}
80+
}
81+
}
82+
83+
const hashRE = /#.*$/
84+
const extRE = /\.(md|html)$/
85+
const slashRE = /\/$/
86+
87+
function normalize (path) {
88+
return path
89+
.replace(hashRE, '')
90+
.replace(extRE, '')
91+
}
92+
93+
function ensureExt (path) {
94+
if (slashRE.test(path)) {
95+
return path
96+
}
97+
const hashMatch = path.match(hashRE)
98+
const hash = hashMatch ? hashMatch[0] : ''
99+
return normalize(path) + '.html' + hash
100+
}
101+
102+
export default {
103+
computed: {
104+
sidebarItems () {
105+
return resolveSidebar(
106+
this.$route,
107+
this.$site
108+
)
109+
}
110+
}
111+
}
112+
</script>
113+
114+
<style lang="stylus">
115+
@import './styles/config.stylus'
116+
117+
.sidebar
118+
ul
119+
padding 0
120+
margin 0
121+
list-style-type none
122+
a
123+
display inline-block
124+
color $textColor
125+
border-left 0.25rem solid transparent
126+
padding 0.25rem
127+
padding-left 1.25rem
128+
&:hover
129+
color $accentColor
130+
&.router-link-active
131+
font-weight 600
132+
color $accentColor
133+
border-left-color $accentColor
134+
.sidebar-group:not(.first)
135+
margin-top 1.5rem
136+
.sidebar-heading
137+
font-size 1.1em
138+
font-weight bold
139+
text-transform uppercase
140+
padding-left 1.5rem
141+
margin-top 0
142+
margin-bottom 0.5rem
143+
</style>

lib/default-theme/nprogress.css

-78
This file was deleted.

lib/default-theme/resolveSidebar.js

-53
This file was deleted.
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
$textColor = #2c3e50
2+
$accentColor = darken(#41b883, 5%)
3+
$borderColor = #eaecef
4+
$codeBgColor = #282c34
5+
$sidebarWidth = 20rem
6+
$contentWidth = 760px
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#nprogress
2+
pointer-events none
3+
.bar
4+
background $accentColor
5+
position fixed
6+
z-index 1031
7+
top 0
8+
left 0
9+
width 100%
10+
height 2px
11+
.peg
12+
display block
13+
position absolute
14+
right 0px
15+
width 100px
16+
height 100%
17+
box-shadow 0 0 10px $accentColor, 0 0 5px $accentColor
18+
opacity 1.0
19+
transform rotate(3deg) translate(0px, -4px)
20+
.spinner
21+
display block
22+
position fixed
23+
z-index 1031
24+
top 15px
25+
right 15px
26+
.spinner-icon
27+
width 18px
28+
height 18px
29+
box-sizing border-box
30+
border solid 2px transparent
31+
border-top-color $accentColor
32+
border-left-color $accentColor
33+
border-radius 50%
34+
animation nprogress-spinner 400ms linear infinite
35+
36+
.nprogress-custom-parent
37+
overflow hidden
38+
position relative
39+
40+
.nprogress-custom-parent #nprogress .spinner,
41+
.nprogress-custom-parent #nprogress .bar
42+
position absolute
43+
44+
@keyframes nprogress-spinner
45+
0% transform rotate(0deg)
46+
100% transform rotate(360deg)

0 commit comments

Comments
 (0)