UNPKG

3.29 kBPlain TextView Raw
1<script>
2import { isActive, hashRE, groupHeaders } from '../util'
3
4export default {
5 functional: true,
6
7 props: ['item', 'sidebarDepth'],
8
9 render (h,
10 {
11 parent: {
12 $page,
13 $site,
14 $route,
15 $themeConfig,
16 $themeLocaleConfig
17 },
18 props: {
19 item,
20 sidebarDepth
21 }
22 }) {
23 // use custom active class matching logic
24 // due to edge case of paths ending with / + hash
25 const selfActive = isActive($route, item.path)
26 // for sidebar: auto pages, a hash link should be active if one of its child
27 // matches
28 const active = item.type === 'auto'
29 ? selfActive || item.children.some(c => isActive($route, item.basePath + '#' + c.slug))
30 : selfActive
31 const link = item.type === 'external'
32 ? renderExternal(h, item.path, item.title || item.path)
33 : renderLink(h, item.path, item.title || item.path, active)
34
35 const maxDepth = [
36 $page.frontmatter.sidebarDepth,
37 sidebarDepth,
38 $themeLocaleConfig.sidebarDepth,
39 $themeConfig.sidebarDepth,
40 1
41 ].find(depth => depth !== undefined)
42
43 const displayAllHeaders = $themeLocaleConfig.displayAllHeaders
44 || $themeConfig.displayAllHeaders
45
46 if (item.type === 'auto') {
47 return [link, renderChildren(h, item.children, item.basePath, $route, maxDepth)]
48 } else if ((active || displayAllHeaders) && item.headers && !hashRE.test(item.path)) {
49 const children = groupHeaders(item.headers)
50 return [link, renderChildren(h, children, item.path, $route, maxDepth)]
51 } else {
52 return link
53 }
54 }
55}
56
57function renderLink (h, to, text, active, level) {
58 const component = {
59 props: {
60 to,
61 activeClass: '',
62 exactActiveClass: ''
63 },
64 class: {
65 active,
66 'sidebar-link': true
67 }
68 }
69
70 if (level > 2) {
71 component.style = {
72 'padding-left': level + 'rem'
73 }
74 }
75
76 return h('RouterLink', component, text)
77}
78
79function renderChildren (h, children, path, route, maxDepth, depth = 1) {
80 if (!children || depth > maxDepth) return null
81 return h('ul', { class: 'sidebar-sub-headers' }, children.map(c => {
82 const active = isActive(route, path + '#' + c.slug)
83 return h('li', { class: 'sidebar-sub-header' }, [
84 renderLink(h, path + '#' + c.slug, c.title, active, c.level - 1),
85 renderChildren(h, c.children, path, route, maxDepth, depth + 1)
86 ])
87 }))
88}
89
90function renderExternal (h, to, text) {
91 return h('a', {
92 attrs: {
93 href: to,
94 target: '_blank',
95 rel: 'noopener noreferrer'
96 },
97 class: {
98 'sidebar-link': true
99 }
100 }, [text, h('OutboundLink')])
101}
102</script>
103
104<style lang="stylus">
105.sidebar .sidebar-sub-headers
106 padding-left 1rem
107 font-size 0.95em
108
109a.sidebar-link
110 font-size 1em
111 font-weight 400
112 display inline-block
113 color $textColor
114 border-left 0.25rem solid transparent
115 padding 0.35rem 1rem 0.35rem 1.25rem
116 line-height 1.4
117 width: 100%
118 box-sizing: border-box
119 &:hover
120 color $accentColor
121 &.active
122 font-weight 600
123 color $accentColor
124 border-left-color $accentColor
125 .sidebar-group &
126 padding-left 2rem
127 .sidebar-sub-headers &
128 padding-top 0.25rem
129 padding-bottom 0.25rem
130 border-left none
131 &.active
132 font-weight 500
133</style>