/
Navbar.vue
74 lines (65 loc) · 2.06 KB
/
Navbar.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<script setup lang="ts">
import NavbarBrand from '@theme/NavbarBrand.vue'
import NavbarItems from '@theme/NavbarItems.vue'
import ToggleColorModeButton from '@theme/ToggleColorModeButton.vue'
import ToggleSidebarButton from '@theme/ToggleSidebarButton.vue'
import { computed, ref } from 'vue'
import {
DeviceType,
useThemeLocaleData,
useUpdateDeviceStatus,
} from '../composables/index.js'
defineEmits(['toggle-sidebar'])
const themeLocale = useThemeLocaleData()
const navbar = ref<HTMLElement | null>(null)
const navbarBrand = ref<HTMLElement | null>(null)
const linksWrapperMaxWidth = ref(0)
const linksWrapperStyle = computed(() => {
if (!linksWrapperMaxWidth.value) {
return {}
}
return {
maxWidth: linksWrapperMaxWidth.value + 'px',
}
})
useUpdateDeviceStatus(
DeviceType.MOBILE,
(mobileDesktopBreakpoint: number): void => {
// avoid overlapping of long title and long navbar links
const navbarHorizontalPadding =
getCssValue(navbar.value, 'paddingLeft') +
getCssValue(navbar.value, 'paddingRight')
if (window.innerWidth < mobileDesktopBreakpoint) {
linksWrapperMaxWidth.value = 0
} else {
linksWrapperMaxWidth.value =
navbar.value!.offsetWidth -
navbarHorizontalPadding -
(navbarBrand.value?.offsetWidth || 0)
}
}
)
function getCssValue(el: HTMLElement | null, property: string): number {
// NOTE: Known bug, will return 'auto' if style value is 'auto'
const val = el?.ownerDocument?.defaultView?.getComputedStyle(el, null)?.[
property
]
const num = Number.parseInt(val, 10)
return Number.isNaN(num) ? 0 : num
}
</script>
<template>
<header ref="navbar" class="navbar">
<ToggleSidebarButton @toggle="$emit('toggle-sidebar')" />
<span ref="navbarBrand">
<NavbarBrand />
</span>
<div class="navbar-items-wrapper" :style="linksWrapperStyle">
<slot name="before" />
<NavbarItems class="can-hide" />
<slot name="after" />
<ToggleColorModeButton v-if="themeLocale.colorModeSwitch" />
<NavbarSearch />
</div>
</header>
</template>