Skip to content

Commit 650089d

Browse files
committed
feat: togglable dropdown on mobile
1 parent 4bf15cb commit 650089d

File tree

4 files changed

+158
-112
lines changed

4 files changed

+158
-112
lines changed

lib/default-theme/DropdownLink.vue

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<template>
2+
<div class="dropdown-wrapper" :class="{ open }">
3+
<div class="dropdown-title" @click="toggle">
4+
<span class="title">{{ item.text }}</span>
5+
<span class="arrow"></span>
6+
</div>
7+
<ul class="nav-dropdown">
8+
<li
9+
class="dropdown-item"
10+
v-for="subItem in item.items"
11+
:key="subItem.link">
12+
<h4 v-if="subItem.type === 'links'">{{ subItem.text }}</h4>
13+
<ul class="dropdown-subitem-wrapper" v-if="subItem.type === 'links'">
14+
<li
15+
class="dropdown-subitem"
16+
v-for="childSubItem in subItem.items"
17+
:key="childSubItem.link">
18+
<nav-link :item="childSubItem"></nav-link>
19+
</li>
20+
</ul>
21+
<nav-link v-else :item="subItem"></nav-link>
22+
</li>
23+
</ul>
24+
</div>
25+
</template>
26+
27+
<script>
28+
import { isExternal, ensureExt } from './util'
29+
import NavLink from './NavLink.vue'
30+
31+
export default {
32+
components: { NavLink },
33+
data() {
34+
return {
35+
open: true
36+
}
37+
},
38+
props: {
39+
item: {
40+
required: true
41+
}
42+
},
43+
methods: {
44+
toggle() {
45+
this.open = !this.open
46+
}
47+
}
48+
}
49+
</script>
50+
51+
<style lang="stylus">
52+
@import './styles/config.styl'
53+
54+
.dropdown-wrapper
55+
.dropdown-title
56+
.arrow
57+
display inline-block
58+
vertical-align middle
59+
margin-top -1px
60+
margin-left 6px
61+
width 0
62+
height 0
63+
border-left 4px solid transparent
64+
border-right 4px solid transparent
65+
border-top 5px solid #ccc
66+
.nav-dropdown
67+
.dropdown-item
68+
color inherit
69+
line-height 1.7rem
70+
h4
71+
margin 0.45rem 0 0
72+
border-top 1px solid #eee
73+
padding 0.45rem 1.5rem 0 1.25rem
74+
.dropdown-subitem-wrapper
75+
padding 0
76+
list-style none
77+
.dropdown-subitem
78+
font-size 0.9em
79+
a
80+
display block
81+
height 1.7rem
82+
line-height 1.7rem
83+
position relative
84+
border-bottom none
85+
font-weight 400
86+
margin-bottom 0
87+
padding 0 1.5rem 0 1.25rem
88+
&:hover
89+
color $accentColor
90+
&.router-link-active
91+
color $accentColor
92+
&::after
93+
content ""
94+
width 0
95+
height 0
96+
border-left 5px solid $accentColor
97+
border-top 4px solid transparent
98+
border-bottom 4px solid transparent
99+
position absolute
100+
top calc(50% - 3px)
101+
left 10px
102+
&:first-child h4
103+
margin-top 0
104+
padding-top 0
105+
border-top 0
106+
107+
@media (max-width: $MQMobile)
108+
.dropdown-wrapper
109+
&.open .dropdown-title
110+
margin-bottom 0.5rem
111+
&:not(.open)
112+
.dropdown-title .arrow
113+
border-top 4px solid transparent
114+
border-bottom 4px solid transparent
115+
border-left 5px solid #ccc
116+
.nav-dropdown
117+
display none
118+
.nav-dropdown
119+
.dropdown-item
120+
h4
121+
border-top 0
122+
margin-top 0
123+
padding-top 0
124+
h4, & > a
125+
font-size 15px
126+
height 2rem
127+
line-height 2rem
128+
.dropdown-subitem
129+
font-size 14px
130+
padding-left 1rem
131+
132+
@media (min-width: $MQMobile)
133+
.dropdown-wrapper
134+
&:hover .nav-dropdown
135+
display block
136+
.nav-dropdown
137+
display none
138+
box-sizing border-box;
139+
max-height calc(100vh - 2.7rem)
140+
overflow-y auto
141+
position absolute
142+
top 100%
143+
right 0
144+
background-color #fff
145+
padding 10px 0
146+
border 1px solid #ddd
147+
border-bottom-color #ccc
148+
text-align left
149+
border-radius 0.25rem
150+
white-space nowrap
151+
margin 0
152+
</style>

lib/default-theme/NavLink.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<router-link
3-
class="router-link"
3+
class="nav-link"
44
:to="link"
55
v-if="!isExternal(link)"
66
:exact="link === '/'"
@@ -9,7 +9,7 @@
99
v-else
1010
:href="link"
1111
target="_blank"
12-
class="router-link"
12+
class="nav-link"
1313
rel="noopener noreferrer"
1414
>{{ item.text }}</a>
1515
</template>

lib/default-theme/NavLinks.vue

+4-92
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,9 @@
55
class="nav-item"
66
v-for="item in userLinks"
77
:key="item.link">
8-
<div
8+
<dropdown-link
99
v-if="item.type === 'links'"
10-
class="dropdown-wrapper">
11-
<span class="dropdown-title">{{ item.text }}</span>
12-
<span class="arrow"></span>
13-
<ul class="nav-dropdown">
14-
<li
15-
class="dropdown-item"
16-
v-for="subItem in item.items"
17-
:key="subItem.link">
18-
<h4 v-if="subItem.type === 'links'">{{ subItem.text }}</h4>
19-
<ul class="dropdown-subitem-wrapper" v-if="subItem.type === 'links'">
20-
<li
21-
class="dropdown-subitem"
22-
v-for="childSubItem in subItem.items"
23-
:key="childSubItem.link">
24-
<nav-link :item="childSubItem"></nav-link>
25-
</li>
26-
</ul>
27-
<nav-link v-else :item="subItem"></nav-link>
28-
</li>
29-
</ul>
30-
</div>
10+
:item="item"></dropdown-link>
3111
<nav-link v-else :item="item"></nav-link>
3212
</div>
3313
<!-- github link -->
@@ -46,9 +26,10 @@
4626
import OutboundLink from './OutboundLink.vue'
4727
import { isActive, resolveNavLinkItem } from './util'
4828
import NavLink from './NavLink.vue'
29+
import DropdownLink from './DropdownLink.vue'
4930
5031
export default {
51-
components: { OutboundLink, NavLink },
32+
components: { OutboundLink, NavLink, DropdownLink },
5233
computed: {
5334
userLinks () {
5435
return (this.$site.themeConfig.nav || []).map((link => {
@@ -89,59 +70,6 @@ export default {
8970
margin-left 1.5rem
9071
font-weight 500
9172
line-height 2rem
92-
.dropdown-wrapper
93-
&:hover .nav-dropdown
94-
display block
95-
.arrow
96-
display inline-block
97-
vertical-align middle
98-
margin-top -1px
99-
margin-left 6px
100-
width 0
101-
height 0
102-
border-left 4px solid transparent
103-
border-right 4px solid transparent
104-
border-top 5px solid #ccc
105-
.nav-dropdown
106-
.dropdown-item
107-
color inherit
108-
line-height 1.7rem
109-
h4
110-
margin 0.45rem 0 0
111-
border-top 1px solid #eee
112-
padding 0.45rem 1.5rem 0 1.25rem
113-
.dropdown-subitem-wrapper
114-
padding 0
115-
list-style none
116-
.dropdown-subitem
117-
font-size 0.9em
118-
a
119-
display block
120-
height 1.7rem
121-
line-height 1.7rem
122-
position relative
123-
border-bottom none
124-
font-weight 400
125-
margin-bottom 0
126-
padding 0 1.5rem 0 1.25rem
127-
&:hover
128-
color $accentColor
129-
&.router-link-active
130-
color $accentColor
131-
&::after
132-
content ""
133-
width 0
134-
height 0
135-
border-left 5px solid $accentColor
136-
border-top 4px solid transparent
137-
border-bottom 4px solid transparent
138-
position absolute
139-
top calc(50% - 3px)
140-
left 10px
141-
&:first-child h4
142-
margin-top 0
143-
padding-top 0
144-
border-top 0
14573
.github-link
14674
margin-left 1.5rem
14775
@@ -157,20 +85,4 @@ export default {
15785
color $textColor
15886
margin-bottom -2px
15987
border-bottom 2px solid lighten($accentColor, 5%)
160-
.nav-dropdown
161-
display none
162-
box-sizing border-box;
163-
max-height calc(100vh - 2.7rem)
164-
overflow-y auto
165-
position absolute
166-
top 100%
167-
right 0
168-
background-color #fff
169-
padding 10px 0
170-
border 1px solid #ddd
171-
border-bottom-color #ccc
172-
text-align left
173-
border-radius 0.25rem
174-
white-space nowrap
175-
margin 0
17688
</style>

lib/default-theme/Sidebar.vue

-18
Original file line numberDiff line numberDiff line change
@@ -87,24 +87,6 @@ function resolveOpenGroupIndex (route, items) {
8787
font-weight 600
8888
font-size 1.1em
8989
padding 0.5rem 0 0.5rem 1.5rem
90-
.nav-item .dropdown-wrapper
91-
.dropdown-title
92-
display inline-block
93-
margin-bottom 0.5rem
94-
.nav-dropdown
95-
.dropdown-item
96-
h4
97-
border-top 0
98-
margin-top 0
99-
padding-top 0
100-
h4, & > a
101-
font-size 15px
102-
height 2rem
103-
line-height 2rem
104-
.dropdown-subitem
105-
font-size 14px
106-
padding-left 1rem
107-
10890
.sidebar-links
10991
margin-top 1.5rem
11092

0 commit comments

Comments
 (0)