Skip to content

Commit

Permalink
feat: sidebarDepth for sidebar groups
Browse files Browse the repository at this point in the history
  • Loading branch information
ulivz committed Feb 3, 2019
1 parent 876b677 commit b0deea0
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 92 deletions.
19 changes: 12 additions & 7 deletions packages/@vuepress/theme-default/components/Page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,25 @@ function resolveNext (page, items) {
function find (page, items, offset) {
const res = []
items.forEach(item => {
if (item.type === 'group') {
res.push(...item.children || [])
} else {
res.push(item)
}
})
flatternItems(items, res)
for (let i = 0; i < res.length; i++) {
const cur = res[i]
if (cur.type === 'page' && cur.path === decodeURIComponent(page.path)) {
return res[i + offset]
}
}
}
function flatternItems (items, res) {
for (let i = 0, l = items.length; i < l; i++) {
if (items[i].type === 'group') {
flatternItems(items[i].children, res)
} else {
res.push(items[i])
}
}
}
</script>

<style lang="stylus">
Expand Down
68 changes: 5 additions & 63 deletions packages/@vuepress/theme-default/components/Sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,79 +2,21 @@
<aside class="sidebar">
<NavLinks/>
<slot name="top"/>
<ul class="sidebar-links" v-if="items.length">
<li v-for="(item, i) in items" :key="i">
<SidebarGroup
v-if="item.type === 'group'"
:item="item"
:first="i === 0"
:open="i === openGroupIndex"
:collapsable="item.collapsable || item.collapsible"
@toggle="toggleGroup(i)"
/>
<SidebarLink v-else :item="item"/>
</li>
</ul>
<SidebarLinks class="sidebar-links" :items="items"/>
<slot name="bottom"/>
</aside>
</template>

<script>
import SidebarGroup from './SidebarGroup.vue'
import SidebarLink from './SidebarLink.vue'
import SidebarLinks from './SidebarLinks.vue'
import NavLinks from './NavLinks.vue'
import { isActive } from '../util'
export default {
components: { SidebarGroup, SidebarLink, NavLinks },
name: 'Sidebar',
props: ['items'],
components: { SidebarLinks, NavLinks },
data () {
return {
openGroupIndex: 0
}
},
created () {
this.refreshIndex()
},
watch: {
'$route' () {
this.refreshIndex()
}
},
methods: {
refreshIndex () {
const index = resolveOpenGroupIndex(
this.$route,
this.items
)
if (index > -1) {
this.openGroupIndex = index
}
},
toggleGroup (index) {
this.openGroupIndex = index === this.openGroupIndex ? -1 : index
},
isActive (page) {
return isActive(this.$route, page.regularPath)
}
}
}
function resolveOpenGroupIndex (route, items) {
for (let i = 0; i < items.length; i++) {
const item = items[i]
if (item.type === 'group' && item.children.some(c => isActive(route, c.path))) {
return i
}
}
return -1
props: ['items']
}
</script>

Expand Down
24 changes: 12 additions & 12 deletions packages/@vuepress/theme-default/components/SidebarGroup.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<section
class="sidebar-group"
:class="{ first, collapsable }"
:class="{ collapsable }"
>
<router-link
class="sidebar-heading clickable"
Expand Down Expand Up @@ -36,28 +36,28 @@
</p>

<DropdownTransition>
<ul
ref="items"
<SidebarLinks
class="sidebar-group-items"
:items="item.children"
v-if="open || !collapsable"
>
<li v-for="child in item.children">
<SidebarLink :item="child"/>
</li>
</ul>
:sidebarDepth="item.sidebarDepth"
/>
</DropdownTransition>
</section>
</template>

<script>
import { isActive } from '../util'
import SidebarLink from './SidebarLink.vue'
import DropdownTransition from './DropdownTransition.vue'
export default {
name: 'SidebarGroup',
props: ['item', 'first', 'open', 'collapsable'],
components: { SidebarLink, DropdownTransition },
props: ['item', 'open', 'collapsable'],
components: { DropdownTransition },
// ref: https://vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components
beforeCreate () {
this.$options.components.SidebarLinks = require('./SidebarLinks.vue').default
},
methods: { isActive }
}
</script>
Expand All @@ -78,7 +78,7 @@ export default {
font-size 1.1em
font-weight bold
// text-transform uppercase
padding 0.35rem 1.5rem
padding 0.35rem 1.5rem 0.35rem 1.25rem
width 100%
box-sizing border-box
margin 0
Expand Down
18 changes: 13 additions & 5 deletions packages/@vuepress/theme-default/components/SidebarLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { isActive, hashRE, groupHeaders } from '../util'
export default {
functional: true,
props: ['item'],
props: ['item', 'sidebarDepth'],
render (h,
{
Expand All @@ -16,7 +16,8 @@ export default {
$themeLocaleConfig
},
props: {
item
item,
sidebarDepth
}
}) {
// use custom active class matching logic
Expand All @@ -28,9 +29,16 @@ export default {
? selfActive || item.children.some(c => isActive($route, item.basePath + '#' + c.slug))
: selfActive
const link = renderLink(h, item.path, item.title || item.path, active)
const configDepth = $page.frontmatter.sidebarDepth != null
? $page.frontmatter.sidebarDepth
: ($themeLocaleConfig.sidebarDepth || $themeConfig.sidebarDepth)
let configDepth
if ($page.frontmatter.sidebarDepth != null) {
configDepth = $page.frontmatter.sidebarDepth
} else if (sidebarDepth != null) {
configDepth = sidebarDepth
} else {
configDepth = $themeLocaleConfig.sidebarDepth || $themeConfig.sidebarDepth
}
const maxDepth = configDepth == null ? 1 : configDepth
const displayAllHeaders = !!$themeLocaleConfig.displayAllHeaders
Expand Down
79 changes: 79 additions & 0 deletions packages/@vuepress/theme-default/components/SidebarLinks.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<template>
<ul v-if="items.length">
<li v-for="(item, i) in items" :key="i">
<SidebarGroup
v-if="item.type === 'group'"
:item="item"
:first="i === 0"
:open="i === openGroupIndex"
:collapsable="item.collapsable || item.collapsible"
@toggle="toggleGroup(i)"
/>
<SidebarLink
v-else
:sidebarDepth="sidebarDepth"
:item="item"
/>
</li>
</ul>
</template>

<script>
import SidebarGroup from './SidebarGroup.vue'
import SidebarLink from './SidebarLink.vue'
import { isActive } from '../util'
export default {
name: 'SidebarLinks',
components: { SidebarGroup, SidebarLink },
props: ['items', 'sidebarDepth'],
data () {
return {
openGroupIndex: 0
}
},
created () {
this.refreshIndex()
},
watch: {
'$route' () {
this.refreshIndex()
}
},
methods: {
refreshIndex () {
const index = resolveOpenGroupIndex(
this.$route,
this.items
)
if (index > -1) {
this.openGroupIndex = index
}
},
toggleGroup (index) {
this.openGroupIndex = index === this.openGroupIndex ? -1 : index
},
isActive (page) {
return isActive(this.$route, page.regularPath)
}
}
}
function resolveOpenGroupIndex (route, items) {
for (let i = 0; i < items.length; i++) {
const item = items[i]
if (item.type === 'group' && item.children.some(c => c.type === 'page' && isActive(route, c.path))) {
return i
}
}
return -1
}
</script>
10 changes: 5 additions & 5 deletions packages/@vuepress/theme-default/util/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,26 +208,26 @@ function ensureEndingSlash (path) {
: path + '/'
}

function resolveItem (item, pages, base, isNested) {
function resolveItem (item, pages, base, groupDepth = 1) {
if (typeof item === 'string') {
return resolvePage(pages, item, base)
} else if (Array.isArray(item)) {
return Object.assign(resolvePage(pages, item[0], base), {
title: item[1]
})
} else {
if (isNested) {
if (groupDepth > 3) {
console.error(
'[vuepress] Nested sidebar groups are not supported. ' +
'Consider using navbar + categories instead.'
'[vuepress] detected a too deep nested sidebar group.'
)
}
const children = item.children || []
return {
type: 'group',
path: item.path,
title: item.title,
children: children.map(child => resolveItem(child, pages, base, true)),
sidebarDepth: item.sidebarDepth,
children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)),
collapsable: item.collapsable !== false
}
}
Expand Down

0 comments on commit b0deea0

Please sign in to comment.