NavLinks.vue 3.8 KB

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