Navbar.vue 3.4 KB

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