Skip to content

Commit a297e13

Browse files
author
zyy
committed
feat: refine group
1 parent 29e7fe4 commit a297e13

File tree

7 files changed

+232
-149
lines changed

7 files changed

+232
-149
lines changed

Diff for: docs/default-theme-config/README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,12 @@ module.exports = {
199199

200200
Sidebar groups are collapsable by default. You can force a group to be always open with `collapsable: false`.
201201

202+
When a group is open, other groups at the same level will be automatically closed. You can isolate a group's open status with `isolated: true`. And then you can config its initial open status with `initialIsolatedOpen: true`.
203+
204+
You can config a group's sidebarDepth with `sidebarDepth: 2`.
205+
206+
You can nest sidebar groups.
207+
202208
### Multiple Sidebars
203209

204210
If you wish to display different sidebars for different sections of content, first organize your pages into directories for each desired section:
@@ -333,7 +339,7 @@ module.exports = {
333339
```
334340

335341
::: warning Note
336-
Unlike the [built-in search](#built-in-search) engine which works out of the box, [Algolia DocSearch](https://community.algolia.com/docsearch/) requires you to submit your site to them for indexing before it starts working.
342+
Unlike the [built-in search](#built-in-search) engine which works out of the box, [Algolia DocSearch](https://community.algolia.com/docsearch/) requires you to submit your site to them for indexing before it starts working.
337343
:::
338344

339345
For more options, refer to [Algolia DocSearch's documentation](https://github.com/algolia/docsearch#docsearch-options).

Diff for: docs/zh/default-theme-config/README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ module.exports = {
164164
}
165165
```
166166

167-
::: tip
167+
::: tip
168168
值得一提的是,当你禁用此选项时,此功能的相应脚本将不会被加载,这是我们性能优化的一个小点。
169169
:::
170170

@@ -196,6 +196,12 @@ module.exports = {
196196

197197
侧边栏的每个子组默认是可折叠的,你可以设置 `collapsable: false` 来让一个组永远都是展开状态。
198198

199+
当一个子组被展开时,跟它同级的其他子组会被折叠。你可以设置 `isolated: true` 来隔离一个组的展开状态。然后你可以设置 `initialIsolatedOpen: true` 来让一个被隔离的组在一开始就处于展开状态。
200+
201+
你可以通过 `sidebarDepth: 2` 来设置一个组的 sidebarDepth。
202+
203+
你可以嵌套组。
204+
199205
### 多个侧边栏
200206

201207
如果你想为不同的页面组来显示不同的侧边栏,首先,将你的页面文件组织成下述的目录结构:

Diff for: lib/default-theme/Page.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ function find (page, items, offset) {
180180
const res = []
181181
items.forEach(item => {
182182
if (item.type === 'group') {
183-
res.push(...item.children || [])
183+
res.push(...(item.descendants || item.children))
184184
} else {
185185
res.push(item)
186186
}

Diff for: lib/default-theme/Sidebar.vue

+41-71
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
v-if="item.type === 'group'"
99
:item="item"
1010
:first="i === 0"
11-
:open="i === openGroupIndex"
1211
:collapsable="item.collapsable"
13-
@toggle="toggleGroup(i)"
1412
/>
1513
<SidebarLink v-else :item="item"/>
1614
</li>
@@ -23,91 +21,63 @@
2321
import SidebarGroup from './SidebarGroup.vue'
2422
import SidebarLink from './SidebarLink.vue'
2523
import NavLinks from './NavLinks.vue'
26-
import { isActive } from './util'
2724
2825
export default {
2926
components: { SidebarGroup, SidebarLink, NavLinks },
3027
31-
props: ['items'],
28+
props: ['items']
29+
}
30+
</script>
3231

33-
data () {
34-
return {
35-
openGroupIndex: 0
36-
}
37-
},
32+
<style lang="stylus">
33+
@import './styles/config.styl';
3834
39-
created () {
40-
this.refreshIndex()
41-
},
35+
.sidebar {
36+
ul {
37+
padding: 0;
38+
margin: 0;
39+
list-style-type: none;
40+
}
4241
43-
watch: {
44-
'$route' () {
45-
this.refreshIndex()
46-
}
47-
},
42+
a {
43+
display: inline-block;
44+
}
4845
49-
methods: {
50-
refreshIndex () {
51-
const index = resolveOpenGroupIndex(
52-
this.$route,
53-
this.items
54-
)
55-
if (index > -1) {
56-
this.openGroupIndex = index
57-
}
58-
},
46+
.nav-links {
47+
display: none;
48+
border-bottom: 1px solid $borderColor;
49+
padding: 0.5rem 0 0.75rem 0;
5950
60-
toggleGroup (index) {
61-
this.openGroupIndex = index === this.openGroupIndex ? -1 : index
62-
},
51+
a {
52+
font-weight: 600;
53+
}
6354
64-
isActive (page) {
65-
return isActive(this.$route, page.path)
55+
.nav-item, .repo-link {
56+
display: block;
57+
line-height: 1.25rem;
58+
font-size: 1.1em;
59+
padding: 0.5rem 0 0.5rem 1.5rem;
6660
}
6761
}
68-
}
6962
70-
function resolveOpenGroupIndex (route, items) {
71-
for (let i = 0; i < items.length; i++) {
72-
const item = items[i]
73-
if (item.type === 'group' && item.children.some(c => isActive(route, c.path))) {
74-
return i
75-
}
63+
.sidebar-links {
64+
padding: 1.5rem 0;
7665
}
77-
return -1
7866
}
79-
</script>
8067
81-
<style lang="stylus">
82-
@import './styles/config.styl'
68+
@media (max-width: $MQMobile) {
69+
.sidebar {
70+
.nav-links {
71+
display: block;
8372
84-
.sidebar
85-
ul
86-
padding 0
87-
margin 0
88-
list-style-type none
89-
a
90-
display inline-block
91-
.nav-links
92-
display none
93-
border-bottom 1px solid $borderColor
94-
padding 0.5rem 0 0.75rem 0
95-
a
96-
font-weight 600
97-
.nav-item, .repo-link
98-
display block
99-
line-height 1.25rem
100-
font-size 1.1em
101-
padding 0.5rem 0 0.5rem 1.5rem
102-
.sidebar-links
103-
padding 1.5rem 0
73+
.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active::after {
74+
top: calc(1rem - 2px);
75+
}
76+
}
10477
105-
@media (max-width: $MQMobile)
106-
.sidebar
107-
.nav-links
108-
display block
109-
.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active::after
110-
top calc(1rem - 2px)
111-
.sidebar-links
112-
padding 1rem 0
78+
.sidebar-links {
79+
padding: 1rem 0;
80+
}
81+
}
82+
}
11383
</style>

Diff for: lib/default-theme/SidebarGroup.vue

+104-33
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<p
77
class="sidebar-heading"
88
:class="{ open }"
9-
@click="$emit('toggle')"
9+
@click="handleClickToggle"
1010
>
1111
<span>{{ item.title }}</span>
1212
<span
@@ -23,55 +23,126 @@
2323
v-if="open || !collapsable"
2424
>
2525
<li v-for="child in item.children">
26-
<SidebarLink :item="child"/>
26+
<SidebarGroup v-if="child.type === 'group'"
27+
:item="child"
28+
:collapsable="child.collapsable"/>
29+
<SidebarLink v-else :item="child" :sidebarDepth="item.sidebarDepth"/>
2730
</li>
2831
</ul>
2932
</DropdownTransition>
3033
</div>
3134
</template>
3235

3336
<script>
37+
import Vue from 'vue'
3438
import SidebarLink from './SidebarLink.vue'
3539
import DropdownTransition from './DropdownTransition.vue'
40+
import { isActive } from './util'
41+
42+
const hub = new Vue()
3643
3744
export default {
3845
name: 'SidebarGroup',
39-
props: ['item', 'first', 'open', 'collapsable'],
40-
components: { SidebarLink, DropdownTransition }
46+
components: { SidebarLink, DropdownTransition },
47+
props: [
48+
'item',
49+
'first',
50+
'collapsable'
51+
],
52+
data () {
53+
return {
54+
open: this.item.isolated && this.item.initialIsolatedOpen || false
55+
}
56+
},
57+
created () {
58+
this.initToggleEvent()
59+
this.refreshOpen()
60+
},
61+
watch: {
62+
'$route' () {
63+
this.refreshOpen()
64+
}
65+
},
66+
methods: {
67+
initToggleEvent () {
68+
const onToggle = this.onToggle.bind(this)
69+
hub.$on('toggle', onToggle)
70+
this.$on('hook:destroyed', () => {
71+
hub.$off('toggle', onToggle)
72+
})
73+
},
74+
refreshOpen () {
75+
const arr = this.item.descendants || this.item.children
76+
if (arr.some(c => isActive(this.$route, c.path))) {
77+
this.open = true
78+
}
79+
},
80+
handleClickToggle () {
81+
this.open = !this.open
82+
if (this.open && !this.item.isolated) {
83+
hub.$emit('toggle', { depth: this.item.depth, target: this })
84+
}
85+
},
86+
onToggle ({ depth, target }) {
87+
if (
88+
target.$parent === this.$parent &&
89+
depth === this.item.depth &&
90+
!this.item.isolated &&
91+
target !== this
92+
) {
93+
this.open = false
94+
}
95+
}
96+
}
4197
}
4298
</script>
4399

44100
<style lang="stylus">
45-
.sidebar-group
46-
&:not(.first)
47-
margin-top 1em
48-
.sidebar-group
49-
padding-left 0.5em
50-
&:not(.collapsable)
51-
.sidebar-heading
52-
cursor auto
53-
color inherit
101+
.sidebar-group {
102+
&:not(.first) {
103+
margin-top: 1em;
104+
}
105+
106+
.sidebar-group {
107+
padding-left: 0.5em;
108+
}
54109
55-
.sidebar-heading
56-
color #999
57-
transition color .15s ease
58-
cursor pointer
59-
font-size 1.1em
60-
font-weight bold
110+
&:not(.collapsable) {
111+
> .sidebar-heading {
112+
cursor: auto;
113+
color: inherit;
114+
}
115+
}
116+
}
117+
118+
.sidebar-heading {
119+
color: #999;
120+
transition: color 0.15s ease;
121+
cursor: pointer;
122+
font-size: 1.1em;
123+
font-weight: bold;
61124
// text-transform uppercase
62-
padding 0 1.5rem
63-
margin-top 0
64-
margin-bottom 0.5rem
65-
&.open, &:hover
66-
color inherit
67-
.arrow
68-
position relative
69-
top -0.12em
70-
left 0.5em
71-
&:.open .arrow
72-
top -0.18em
125+
padding: 0 1.5rem;
126+
margin-top: 0;
127+
margin-bottom: 0.5rem;
128+
129+
&.open, &:hover {
130+
color: inherit;
131+
}
73132
74-
.sidebar-group-items
75-
transition height .1s ease-out
76-
overflow hidden
133+
.arrow {
134+
position: relative;
135+
top: -0.12em;
136+
left: 0.5em;
137+
}
138+
139+
&:.open .arrow {
140+
top: -0.18em;
141+
}
142+
}
143+
144+
.sidebar-group-items {
145+
transition: height 0.1s ease-out;
146+
overflow: hidden;
147+
}
77148
</style>

0 commit comments

Comments
 (0)