mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 03:43:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<script>
 | 
						|
import { isActive, hashRE, groupHeaders } from './util'
 | 
						|
import AppLink from './AppLink'
 | 
						|
 | 
						|
export default {
 | 
						|
  functional: true,
 | 
						|
  components: {AppLink},
 | 
						|
  props: ['item', 'open', 'collapsable'],
 | 
						|
  render (h, { parent: { $page, $site, $route }, props: { item, open, collapsable }}) {
 | 
						|
    // 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 hidden = $site.themeConfig.hiddenLinks.includes(item.path);
 | 
						|
    const link = renderLink(h, item.path, item.title || item.path, active, hidden)
 | 
						|
    const configDepth = $page.frontmatter.sidebarDepth != null
 | 
						|
      ? $page.frontmatter.sidebarDepth
 | 
						|
      : $site.themeConfig.sidebarDepth
 | 
						|
    const maxDepth = configDepth == null ? 1 : configDepth
 | 
						|
    if (item.type === 'auto') {
 | 
						|
      return [link, renderChildren(h, item.children, item.basePath, $route, maxDepth)]
 | 
						|
    } else if (active && item.headers && !hashRE.test(item.path)) {
 | 
						|
      const children = groupHeaders(item.headers)
 | 
						|
      return [link, renderChildren(h, children, item.path, $route, maxDepth)]
 | 
						|
    } else if (collapsable && open && hidden && !active && 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, hidden) {
 | 
						|
  if (~to.indexOf('http')) return h('a',
 | 
						|
    {
 | 
						|
      attrs: {
 | 
						|
        href: to
 | 
						|
      },
 | 
						|
      class: 'sidebar-link'
 | 
						|
    },
 | 
						|
    text)
 | 
						|
  return h('router-link', {
 | 
						|
    props: {
 | 
						|
      to,
 | 
						|
      activeClass: '',
 | 
						|
      exactActiveClass: ''
 | 
						|
    },
 | 
						|
    class: {
 | 
						|
      active,
 | 
						|
      hidden,
 | 
						|
      '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>
 | 
						|
 | 
						|
<style lang="stylus">
 | 
						|
@import './styles/config.styl'
 | 
						|
 | 
						|
.sidebar .sidebar-sub-headers
 | 
						|
  padding-left 1rem
 | 
						|
  font-size 0.95em
 | 
						|
 | 
						|
a.sidebar-link
 | 
						|
  font-weight 400
 | 
						|
  display inline-block
 | 
						|
  color $textColor
 | 
						|
  border-left 0.25rem solid transparent
 | 
						|
  padding 0.35rem 1rem 0.35rem 1.25rem
 | 
						|
  line-height 1.4
 | 
						|
  width: 100%
 | 
						|
  box-sizing: border-box
 | 
						|
  &:hover
 | 
						|
    color $accentColor
 | 
						|
  &.active
 | 
						|
    font-weight 600
 | 
						|
    color $accentColor
 | 
						|
    border-left-color $accentColor
 | 
						|
  &.hidden
 | 
						|
    display: none
 | 
						|
  .sidebar-group &
 | 
						|
    padding-left 2rem
 | 
						|
  .sidebar-sub-headers &
 | 
						|
    padding-top 0.25rem
 | 
						|
    padding-bottom 0.25rem
 | 
						|
    border-left none
 | 
						|
    &.active
 | 
						|
      font-weight 500
 | 
						|
</style>
 |