UNPKG

3.8 kBPlain TextView Raw
1<template>
2 <nav
3 v-if="userLinks.length || repoLink"
4 class="nav-links"
5 >
6 <!-- user links -->
7 <div
8 v-for="item in userLinks"
9 :key="item.link"
10 class="nav-item"
11 >
12 <DropdownLink
13 v-if="item.type === 'links'"
14 :item="item"
15 />
16 <NavLink
17 v-else
18 :item="item"
19 />
20 </div>
21
22 <!-- repo link -->
23 <a
24 v-if="repoLink"
25 :href="repoLink"
26 class="repo-link"
27 target="_blank"
28 rel="noopener noreferrer"
29 >
30 {{ repoLabel }}
31 <OutboundLink />
32 </a>
33 </nav>
34</template>
35
36<script>
37import DropdownLink from '@theme/components/DropdownLink.vue'
38import { resolveNavLinkItem } from '../util'
39import NavLink from '@theme/components/NavLink.vue'
40
41export default {
42 name: 'NavLinks',
43
44 components: {
45 NavLink,
46 DropdownLink
47 },
48
49 computed: {
50 userNav () {
51 return this.$themeLocaleConfig.nav || this.$site.themeConfig.nav || []
52 },
53
54 nav () {
55 const { locales } = this.$site
56 if (locales && Object.keys(locales).length > 1) {
57 const currentLink = this.$page.path
58 const routes = this.$router.options.routes
59 const themeLocales = this.$site.themeConfig.locales || {}
60 const languageDropdown = {
61 text: this.$themeLocaleConfig.selectText || 'Languages',
62 ariaLabel: this.$themeLocaleConfig.ariaLabel || 'Select language',
63 items: Object.keys(locales).map(path => {
64 const locale = locales[path]
65 const text = themeLocales[path] && themeLocales[path].label || locale.lang
66 let link
67 // Stay on the current page
68 if (locale.lang === this.$lang) {
69 link = currentLink
70 } else {
71 // Try to stay on the same page
72 link = currentLink.replace(this.$localeConfig.path, path)
73 // fallback to homepage
74 if (!routes.some(route => route.path === link)) {
75 link = path
76 }
77 }
78 return { text, link }
79 })
80 }
81 return [...this.userNav, languageDropdown]
82 }
83 return this.userNav
84 },
85
86 userLinks () {
87 return (this.nav || []).map(link => {
88 return Object.assign(resolveNavLinkItem(link), {
89 items: (link.items || []).map(resolveNavLinkItem)
90 })
91 })
92 },
93
94 repoLink () {
95 const { repo } = this.$site.themeConfig
96 if (repo) {
97 return /^https?:/.test(repo)
98 ? repo
99 : `https://github.com/${repo}`
100 }
101 return null
102 },
103
104 repoLabel () {
105 if (!this.repoLink) return
106 if (this.$site.themeConfig.repoLabel) {
107 return this.$site.themeConfig.repoLabel
108 }
109
110 const repoHost = this.repoLink.match(/^https?:\/\/[^/]+/)[0]
111 const platforms = ['GitHub', 'GitLab', 'Bitbucket']
112 for (let i = 0; i < platforms.length; i++) {
113 const platform = platforms[i]
114 if (new RegExp(platform, 'i').test(repoHost)) {
115 return platform
116 }
117 }
118
119 return 'Source'
120 }
121 }
122}
123</script>
124
125<style lang="stylus">
126.nav-links
127 display inline-block
128 a
129 line-height 1.4rem
130 color inherit
131 &:hover, &.router-link-active
132 color $accentColor
133 .nav-item
134 position relative
135 display inline-block
136 margin-left 1.5rem
137 line-height 2rem
138 &:first-child
139 margin-left 0
140 .repo-link
141 margin-left 1.5rem
142
143@media (max-width: $MQMobile)
144 .nav-links
145 .nav-item, .repo-link
146 margin-left 0
147
148@media (min-width: $MQMobile)
149 .nav-links a
150 &:hover, &.router-link-active
151 color $textColor
152 .nav-item > a:not(.external)
153 &:hover, &.router-link-active
154 margin-bottom -2px
155 border-bottom 2px solid lighten($accentColor, 8%)
156</style>