UNPKG

5.64 kBPlain TextView Raw
1<template>
2 <div
3 class="dropdown-wrapper"
4 :class="{ open }"
5 >
6 <button
7 class="dropdown-title"
8 type="button"
9 :aria-label="dropdownAriaLabel"
10 @click="handleDropdown"
11 >
12 <span class="title">{{ item.text }}</span>
13 <span
14 class="arrow down"
15 />
16 </button>
17 <button
18 class="mobile-dropdown-title"
19 type="button"
20 :aria-label="dropdownAriaLabel"
21 @click="setOpen(!open)"
22 >
23 <span class="title">{{ item.text }}</span>
24 <span
25 class="arrow"
26 :class="open ? 'down' : 'right'"
27 />
28 </button>
29
30 <DropdownTransition>
31 <ul
32 v-show="open"
33 class="nav-dropdown"
34 >
35 <li
36 v-for="(subItem, index) in item.items"
37 :key="subItem.link || index"
38 class="dropdown-item"
39 >
40 <h4 v-if="subItem.type === 'links'">
41 {{ subItem.text }}
42 </h4>
43
44 <ul
45 v-if="subItem.type === 'links'"
46 class="dropdown-subitem-wrapper"
47 >
48 <li
49 v-for="childSubItem in subItem.items"
50 :key="childSubItem.link"
51 class="dropdown-subitem"
52 >
53 <NavLink
54 :item="childSubItem"
55 @focusout="
56 isLastItemOfArray(childSubItem, subItem.items) &&
57 isLastItemOfArray(subItem, item.items) &&
58 setOpen(false)
59 "
60 />
61 </li>
62 </ul>
63
64 <NavLink
65 v-else
66 :item="subItem"
67 @focusout="isLastItemOfArray(subItem, item.items) && setOpen(false)"
68 />
69 </li>
70 </ul>
71 </DropdownTransition>
72 </div>
73</template>
74
75<script>
76import NavLink from '@theme/components/NavLink.vue'
77import DropdownTransition from '@theme/components/DropdownTransition.vue'
78import last from 'lodash/last'
79
80export default {
81 name: 'DropdownLink',
82
83 components: {
84 NavLink,
85 DropdownTransition
86 },
87
88 props: {
89 item: {
90 required: true
91 }
92 },
93
94 data () {
95 return {
96 open: false
97 }
98 },
99
100 computed: {
101 dropdownAriaLabel () {
102 return this.item.ariaLabel || this.item.text
103 }
104 },
105
106 watch: {
107 $route () {
108 this.open = false
109 }
110 },
111
112 methods: {
113 setOpen (value) {
114 this.open = value
115 },
116
117 isLastItemOfArray (item, array) {
118 return last(array) === item
119 },
120
121 /**
122 * Open the dropdown when user tab and click from keyboard.
123 *
124 * Use event.detail to detect tab and click from keyboard. Ref: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
125 * The Tab + Click is UIEvent > KeyboardEvent, so the detail is 0.
126 */
127 handleDropdown () {
128 const isTriggerByTab = event.detail === 0
129 if (isTriggerByTab) this.setOpen(!this.open)
130 }
131 }
132}
133</script>
134
135<style lang="stylus">
136.dropdown-wrapper
137 cursor pointer
138 .dropdown-title
139 display block
140 font-size 0.9rem
141 font-family inherit
142 cursor inherit
143 padding inherit
144 line-height 1.4rem
145 background transparent
146 border none
147 font-weight 500
148 color $textColor
149 &:hover
150 border-color transparent
151 .arrow
152 vertical-align middle
153 margin-top -1px
154 margin-left 0.4rem
155 .mobile-dropdown-title
156 @extends .dropdown-title
157 display none
158 font-weight 600
159 font-size inherit
160 &:hover
161 color $accentColor
162 .nav-dropdown
163 .dropdown-item
164 color inherit
165 line-height 1.7rem
166 h4
167 margin 0.45rem 0 0
168 border-top 1px solid #eee
169 padding 1rem 1.5rem 0.45rem 1.25rem
170 .dropdown-subitem-wrapper
171 padding 0
172 list-style none
173 .dropdown-subitem
174 font-size 0.9em
175 a
176 display block
177 line-height 1.7rem
178 position relative
179 border-bottom none
180 font-weight 400
181 margin-bottom 0
182 padding 0 1.5rem 0 1.25rem
183 &:hover
184 color $accentColor
185 &.router-link-active
186 color $accentColor
187 &::after
188 content ""
189 width 0
190 height 0
191 border-left 5px solid $accentColor
192 border-top 3px solid transparent
193 border-bottom 3px solid transparent
194 position absolute
195 top calc(50% - 2px)
196 left 9px
197 &:first-child h4
198 margin-top 0
199 padding-top 0
200 border-top 0
201
202@media (max-width: $MQMobile)
203 .dropdown-wrapper
204 &.open .dropdown-title
205 margin-bottom 0.5rem
206 .dropdown-title
207 display: none
208 .mobile-dropdown-title
209 display: block
210 .nav-dropdown
211 transition height .1s ease-out
212 overflow hidden
213 .dropdown-item
214 h4
215 border-top 0
216 margin-top 0
217 padding-top 0
218 h4, & > a
219 font-size 15px
220 line-height 2rem
221 .dropdown-subitem
222 font-size 14px
223 padding-left 1rem
224
225@media (min-width: $MQMobile)
226 .dropdown-wrapper
227 height 1.8rem
228 &:hover .nav-dropdown,
229 &.open .nav-dropdown
230 // override the inline style.
231 display block !important
232 .nav-dropdown
233 display none
234 // Avoid height shaked by clicking
235 height auto !important
236 box-sizing border-box;
237 max-height calc(100vh - 2.7rem)
238 overflow-y auto
239 position absolute
240 top 100%
241 right 0
242 background-color #fff
243 padding 0.6rem 0
244 border 1px solid #ddd
245 border-bottom-color #ccc
246 text-align left
247 border-radius 0.25rem
248 white-space nowrap
249 margin 0
250</style>