@@ -17,6 +17,28 @@ export type Breakpoints =
17
17
18
18
export type Alignments = Directions | Breakpoints
19
19
20
+ export const getNextActiveElement = (
21
+ list : HTMLElement [ ] ,
22
+ activeElement : HTMLElement ,
23
+ shouldGetNext : boolean ,
24
+ isCycleAllowed : boolean ,
25
+ ) => {
26
+ const listLength = list . length
27
+ let index = list . indexOf ( activeElement )
28
+
29
+ if ( index === - 1 ) {
30
+ return ! shouldGetNext && isCycleAllowed ? list [ listLength - 1 ] : list [ 0 ]
31
+ }
32
+
33
+ index += shouldGetNext ? 1 : - 1
34
+
35
+ if ( isCycleAllowed ) {
36
+ index = ( index + listLength ) % listLength
37
+ }
38
+
39
+ return list [ Math . max ( 0 , Math . min ( index , listLength - 1 ) ) ]
40
+ }
41
+
20
42
const getPlacement = (
21
43
placement : Placement ,
22
44
direction : string | undefined ,
@@ -214,13 +236,19 @@ const CDropdown = defineComponent({
214
236
popper . value && initPopper ( dropdownToggleRef . value , dropdownMenuRef . value , popperConfig )
215
237
window . addEventListener ( 'mouseup' , handleMouseUp )
216
238
window . addEventListener ( 'keyup' , handleKeyup )
239
+ dropdownToggleRef . value . addEventListener ( 'keydown' , handleKeydown )
240
+ dropdownMenuRef . value . addEventListener ( 'keydown' , handleKeydown )
217
241
emit ( 'show' )
218
242
return
219
243
}
220
244
221
245
popper . value && destroyPopper ( )
222
246
window . removeEventListener ( 'mouseup' , handleMouseUp )
223
247
window . removeEventListener ( 'keyup' , handleKeyup )
248
+ dropdownToggleRef . value &&
249
+ dropdownToggleRef . value . removeEventListener ( 'keydown' , handleKeydown )
250
+ dropdownMenuRef . value &&
251
+ dropdownMenuRef . value . removeEventListener ( 'keydown' , handleKeydown )
224
252
emit ( 'hide' )
225
253
} )
226
254
@@ -235,6 +263,15 @@ const CDropdown = defineComponent({
235
263
provide ( 'dropdownToggleRef' , dropdownToggleRef )
236
264
provide ( 'dropdownMenuRef' , dropdownMenuRef )
237
265
266
+ const handleKeydown = ( event : KeyboardEvent ) => {
267
+ if ( visible . value && dropdownMenuRef . value && ( event . key === 'ArrowDown' || event . key === 'ArrowUp' ) ) {
268
+ event . preventDefault ( )
269
+ const target = event . target as HTMLElement
270
+ const items : HTMLElement [ ] = Array . from ( dropdownMenuRef . value . querySelectorAll ( '.dropdown-item:not(.disabled):not(:disabled)' ) )
271
+ getNextActiveElement ( items , target , event . key === 'ArrowDown' , true ) . focus ( )
272
+ }
273
+ }
274
+
238
275
const handleKeyup = ( event : KeyboardEvent ) => {
239
276
if ( props . autoClose === false ) {
240
277
return
0 commit comments