Navbar.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <template>
  2. <header class="navbar">
  3. <SidebarButton @toggle-sidebar="$emit('toggle-sidebar')" />
  4. <RouterLink
  5. :to="$localePath"
  6. class="home-link"
  7. >
  8. <img
  9. v-if="$site.themeConfig.logo"
  10. class="logo"
  11. :src="$withBase($site.themeConfig.logo)"
  12. :alt="$siteTitle"
  13. >
  14. <span
  15. v-if="$siteTitle"
  16. ref="siteName"
  17. class="site-name"
  18. :class="{ 'can-hide': $site.themeConfig.logo }"
  19. >{{ $siteTitle }}</span>
  20. </RouterLink>
  21. <div
  22. class="links"
  23. :style="linksWrapMaxWidth ? {
  24. 'max-width': linksWrapMaxWidth + 'px'
  25. } : {}"
  26. >
  27. <AlgoliaSearchBox
  28. v-if="isAlgoliaSearch"
  29. :options="algolia"
  30. />
  31. <SearchBox v-else-if="$site.themeConfig.search !== false && $page.frontmatter.search !== false" />
  32. <NavLinks class="can-hide" />
  33. </div>
  34. </header>
  35. </template>
  36. <script>
  37. import AlgoliaSearchBox from '@theme/components/AlgoliaSearchBox'
  38. import SearchBox from '@SearchBox'
  39. import SidebarButton from '@theme/components/SidebarButton.vue'
  40. import NavLinks from '@theme/components/NavLinks.vue'
  41. export default {
  42. name: 'Navbar',
  43. components: {
  44. SidebarButton,
  45. NavLinks,
  46. SearchBox,
  47. AlgoliaSearchBox
  48. },
  49. data () {
  50. return {
  51. linksWrapMaxWidth: null
  52. }
  53. },
  54. computed: {
  55. algolia () {
  56. return this.$themeLocaleConfig.algolia || this.$site.themeConfig.algolia || {}
  57. },
  58. isAlgoliaSearch () {
  59. return this.algolia && this.algolia.apiKey && this.algolia.indexName
  60. }
  61. },
  62. mounted () {
  63. const MOBILE_DESKTOP_BREAKPOINT = 719 // refer to config.styl
  64. const NAVBAR_VERTICAL_PADDING = parseInt(css(this.$el, 'paddingLeft')) + parseInt(css(this.$el, 'paddingRight'))
  65. const handleLinksWrapWidth = () => {
  66. if (document.documentElement.clientWidth < MOBILE_DESKTOP_BREAKPOINT) {
  67. this.linksWrapMaxWidth = null
  68. } else {
  69. this.linksWrapMaxWidth = this.$el.offsetWidth - NAVBAR_VERTICAL_PADDING
  70. - (this.$refs.siteName && this.$refs.siteName.offsetWidth || 0)
  71. }
  72. }
  73. handleLinksWrapWidth()
  74. window.addEventListener('resize', handleLinksWrapWidth, false)
  75. }
  76. }
  77. function css (el, property) {
  78. // NOTE: Known bug, will return 'auto' if style value is 'auto'
  79. const win = el.ownerDocument.defaultView
  80. // null means not to return pseudo styles
  81. return win.getComputedStyle(el, null)[property]
  82. }
  83. </script>
  84. <style lang="stylus">
  85. $navbar-vertical-padding = 0.7rem
  86. $navbar-horizontal-padding = 1.5rem
  87. .navbar
  88. padding $navbar-vertical-padding $navbar-horizontal-padding
  89. line-height $navbarHeight - 1.4rem
  90. a, span, img
  91. display inline-block
  92. .logo
  93. height $navbarHeight - 1.4rem
  94. min-width $navbarHeight - 1.4rem
  95. margin-right 0.8rem
  96. vertical-align top
  97. .site-name
  98. font-size 1.3rem
  99. font-weight 600
  100. color $textColor
  101. position relative
  102. .links
  103. padding-left 1.5rem
  104. box-sizing border-box
  105. background-color white
  106. white-space nowrap
  107. font-size 0.9rem
  108. position absolute
  109. right $navbar-horizontal-padding
  110. top $navbar-vertical-padding
  111. display flex
  112. .search-box
  113. flex: 0 0 auto
  114. vertical-align top
  115. @media (max-width: $MQMobile)
  116. .navbar
  117. padding-left 4rem
  118. .can-hide
  119. display none
  120. .links
  121. padding-left 1.5rem
  122. .site-name
  123. width calc(100vw - 9.4rem)
  124. overflow hidden
  125. white-space nowrap
  126. text-overflow ellipsis
  127. </style>