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