1
1
<script lang="ts" setup>
2
2
import { useWindowScroll } from ' @vueuse/core'
3
3
import { onContentUpdated } from ' vitepress'
4
- import { computed , onMounted , ref , shallowRef } from ' vue'
4
+ import { computed , onMounted , ref } from ' vue'
5
5
import { useData } from ' ../composables/data'
6
- import { getHeaders , type MenuItem } from ' ../composables/outline'
6
+ import { useLocalNav } from ' ../composables/local-nav'
7
+ import { getHeaders } from ' ../composables/outline'
7
8
import { useSidebar } from ' ../composables/sidebar'
8
9
import VPLocalNavOutlineDropdown from ' ./VPLocalNavOutlineDropdown.vue'
9
10
import VPIconAlignLeft from ' ./icons/VPIconAlignLeft.vue'
@@ -18,9 +19,9 @@ defineEmits<{
18
19
19
20
const { theme, frontmatter } = useData ()
20
21
const { hasSidebar } = useSidebar ()
22
+ const { headers } = useLocalNav ()
21
23
const { y } = useWindowScroll ()
22
24
23
- const headers = shallowRef <MenuItem []>([])
24
25
const navHeight = ref (0 )
25
26
26
27
onMounted (() => {
@@ -36,37 +37,44 @@ onContentUpdated(() => {
36
37
})
37
38
38
39
const empty = computed (() => {
39
- return headers .value .length === 0 && ! hasSidebar .value
40
+ return headers .value .length === 0
41
+ })
42
+
43
+ const emptyAndNoSidebar = computed (() => {
44
+ return empty .value && ! hasSidebar .value
40
45
})
41
46
42
47
const classes = computed (() => {
43
48
return {
44
49
VPLocalNav: true ,
45
- fixed: empty .value ,
46
- ' reached-top' : y .value >= navHeight .value
50
+ ' has-sidebar' : hasSidebar .value ,
51
+ empty: empty .value ,
52
+ fixed: emptyAndNoSidebar .value
47
53
}
48
54
})
49
55
</script >
50
56
51
57
<template >
52
58
<div
53
- v-if =" frontmatter.layout !== 'home' && (!empty || y >= navHeight)"
59
+ v-if =" frontmatter.layout !== 'home' && (!emptyAndNoSidebar || y >= navHeight)"
54
60
:class =" classes"
55
61
>
56
- <button
57
- v-if =" hasSidebar"
58
- class =" menu"
59
- :aria-expanded =" open"
60
- aria-controls =" VPSidebarNav"
61
- @click =" $emit('open-menu')"
62
- >
63
- <VPIconAlignLeft class =" menu-icon" />
64
- <span class =" menu-text" >
65
- {{ theme.sidebarMenuLabel || 'Menu' }}
66
- </span >
67
- </button >
68
-
69
- <VPLocalNavOutlineDropdown :headers =" headers" :navHeight =" navHeight" />
62
+ <div class =" container" >
63
+ <button
64
+ v-if =" hasSidebar"
65
+ class =" menu"
66
+ :aria-expanded =" open"
67
+ aria-controls =" VPSidebarNav"
68
+ @click =" $emit('open-menu')"
69
+ >
70
+ <VPIconAlignLeft class =" menu-icon" />
71
+ <span class =" menu-text" >
72
+ {{ theme.sidebarMenuLabel || 'Menu' }}
73
+ </span >
74
+ </button >
75
+
76
+ <VPLocalNavOutlineDropdown :headers =" headers" :navHeight =" navHeight" />
77
+ </div >
70
78
</div >
71
79
</template >
72
80
@@ -77,10 +85,6 @@ const classes = computed(() => {
77
85
/* rtl:ignore*/
78
86
left : 0 ;
79
87
z-index : var (--vp-z-index-local-nav );
80
- display : flex ;
81
- justify-content : space-between ;
82
- align-items : center ;
83
- border-top : 1px solid var (--vp-c-gutter );
84
88
border-bottom : 1px solid var (--vp-c-gutter );
85
89
padding-top : var (--vp-layout-top-height , 0px );
86
90
width : 100% ;
@@ -91,16 +95,38 @@ const classes = computed(() => {
91
95
position : fixed ;
92
96
}
93
97
94
- .VPLocalNav.reached-top {
95
- border-top-color : transparent ;
98
+ @media (min-width : 960px ) {
99
+ .VPLocalNav {
100
+ top : var (--vp-nav-height );
101
+ }
102
+
103
+ .VPLocalNav.has-sidebar {
104
+ padding-left : var (--vp-sidebar-width );
105
+ }
106
+
107
+ .VPLocalNav.empty {
108
+ display : none ;
109
+ }
96
110
}
97
111
98
- @media (min-width : 960 px ) {
112
+ @media (min-width : 1280 px ) {
99
113
.VPLocalNav {
100
114
display : none ;
101
115
}
102
116
}
103
117
118
+ @media (min-width : 1440px ) {
119
+ .VPLocalNav.has-sidebar {
120
+ padding-left : calc ((100vw - var (--vp-layout-max-width )) / 2 + var (--vp-sidebar-width ));
121
+ }
122
+ }
123
+
124
+ .container {
125
+ display : flex ;
126
+ justify-content : space-between ;
127
+ align-items : center ;
128
+ }
129
+
104
130
.menu {
105
131
display : flex ;
106
132
align-items : center ;
@@ -123,6 +149,12 @@ const classes = computed(() => {
123
149
}
124
150
}
125
151
152
+ @media (min-width : 960px ) {
153
+ .menu {
154
+ display : none ;
155
+ }
156
+ }
157
+
126
158
.menu-icon {
127
159
margin-right : 8px ;
128
160
width : 16px ;
0 commit comments