documentation/.vuepress/theme/SidebarLink.vue
2018-07-28 13:47:12 -07:00

58 lines
2.4 KiB
Vue

<script>
import { isActive, hashRE, groupHeaders } from './util';
export default {
functional: true,
props: ['item'],
render(h, { parent: { $page, $site, $route }, props: { item } }) {
// use custom active class matching logic
// due to edge case of paths ending with / + hash
const selfActive = isActive($route, item.path);
// for sidebar: auto pages, a hash link should be active if one of its child
// matches
const active = item.type === 'auto'
? 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
: $site.themeConfig.sidebarDepth;
const maxDepth = configDepth == null ? 1 : configDepth;
const displayAllHeaders = ! ! $site.themeConfig.displayAllHeaders;
if (item.type === 'auto') {
return [link, renderChildren(h, item.children, item.basePath, $route, maxDepth)];
} else if ((active || displayAllHeaders) && item.headers && ! hashRE.test(item.path)) {
const children = groupHeaders(item.headers);
return [link, renderChildren(h, children, item.path, $route, maxDepth)];
} else {
return link;
}
}
};
function renderLink(h, to, text, active) {
return h('router-link', {
props: {
to,
activeClass: '',
exactActiveClass: ''
},
class: {
active,
'sidebar-link': true
}
}, text);
}
function renderChildren(h, children, path, route, maxDepth, depth = 1) {
if (! children || depth > maxDepth) return null;
return h('ul', { class: 'sidebar-sub-headers' }, children.map(c => {
const active = isActive(route, path + '#' + c.slug);
return h('li', { class: 'sidebar-sub-header' }, [
renderLink(h, path + '#' + c.slug, c.title, active),
renderChildren(h, c.children, path, route, maxDepth, depth + 1)
]);
}));
}
</script>