@@ -26,55 +26,51 @@ export function init(id, invoke, options) {
2626 }
2727
2828 const keydown = e => {
29- if ( popover . toggleElement . classList . contains ( 'show' ) ) {
30- const items = popover . toggleMenu . querySelectorAll ( '.dropdown-item:not(.search, .disabled)' )
31- let activeItem = popover . toggleMenu . querySelector ( '.dropdown-item.preActive' )
32- if ( activeItem == null ) activeItem = popover . toggleMenu . querySelector ( '.dropdown-item.active' )
33-
34- if ( activeItem ) {
35- if ( items . length > 1 ) {
36- activeItem . classList . remove ( 'preActive' )
37- if ( e . key === "ArrowUp" ) {
38- do {
39- activeItem = activeItem . previousElementSibling
40- }
41- while ( activeItem && ! activeItem . classList . contains ( 'dropdown-item' ) )
42- if ( ! activeItem ) {
43- activeItem = items [ items . length - 1 ]
44- }
45- activeItem . classList . add ( 'preActive' )
46- scrollToActive ( popover . toggleMenu , activeItem )
47- e . preventDefault ( )
48- e . stopPropagation ( )
49- }
50- else if ( e . key === "ArrowDown" ) {
51- do {
52- activeItem = activeItem . nextElementSibling
53- }
54- while ( activeItem && ! activeItem . classList . contains ( 'dropdown-item' ) )
55- if ( ! activeItem ) {
56- activeItem = items [ 0 ]
57- }
58- activeItem . classList . add ( 'preActive' )
59- scrollToActive ( popover . toggleMenu , activeItem )
60- e . preventDefault ( )
61- e . stopPropagation ( )
62- }
29+ const menu = popover . toggleMenu ;
30+ const key = e . key ;
31+ if ( key === "Enter" || key === 'NumpadEnter' ) {
32+ menu . classList . remove ( 'show' )
33+ let index = indexOf ( el , activeItem )
34+ invoke . invokeMethodAsync ( confirmMethodCallback , index )
35+ }
36+ else if ( key === 'ArrowUp' || key === 'ArrowDown' ) {
37+ e . preventDefault ( ) ;
38+
39+ if ( menu . querySelector ( '.dropdown-virtual' ) ) {
40+ return ;
41+ }
42+
43+ const items = [ ...menu . querySelectorAll ( '.dropdown-item:not(.disabled)' ) ] ;
44+ if ( items . length > 0 ) {
45+ let current = menu . querySelector ( '.active' ) ;
46+ if ( current !== null ) {
47+ current . classList . remove ( 'active' ) ;
6348 }
6449
65- if ( e . key === "Enter" ) {
66- popover . toggleMenu . classList . remove ( 'show' )
67- let index = indexOf ( el , activeItem )
68- invoke . invokeMethodAsync ( confirmMethodCallback , index )
50+ let index = current === null ? - 1 : items . indexOf ( current ) ;
51+ index = key === 'ArrowUp' ? index - 1 : index + 1 ;
52+ if ( index < 0 ) {
53+ index = items . length - 1 ;
6954 }
55+ else if ( index > items . length - 1 ) {
56+ index = 0 ;
57+ }
58+ items [ index ] . classList . add ( 'active' ) ;
59+ const top = getTop ( menu , index ) ;
60+ const hehavior = el . getAttribute ( 'data-bb-scroll-behavior' ) ?? 'smooth' ;
61+ menu . scrollTo ( { top : top , left : 0 , behavior : hehavior } ) ;
7062 }
7163 }
7264 }
7365
7466 EventHandler . on ( el , 'shown.bs.dropdown' , shown ) ;
7567 EventHandler . on ( el , 'keydown' , keydown )
7668
77- const onSearch = debounce ( v => invoke . invokeMethodAsync ( searchMethodCallback , v ) ) ;
69+ const onSearch = debounce ( async v => {
70+ search . parentElement . classList . add ( 'l' ) ;
71+ await invoke . invokeMethodAsync ( searchMethodCallback , v ) ;
72+ search . parentElement . classList . remove ( 'l' ) ;
73+ } ) ;
7874 if ( search ) {
7975 Input . composition ( search , onSearch ) ;
8076 }
@@ -87,6 +83,19 @@ export function init(id, invoke, options) {
8783 Data . set ( id , select ) ;
8884}
8985
86+ const getTop = ( menu , index ) => {
87+ const styles = getComputedStyle ( menu )
88+ const maxHeight = parseInt ( styles . maxHeight ) / 2
89+ const itemHeight = getHeight ( menu . querySelector ( '.dropdown-item' ) )
90+ const height = itemHeight * index
91+ const count = Math . floor ( maxHeight / itemHeight ) ;
92+ let top = 0 ;
93+ if ( height > maxHeight ) {
94+ top = itemHeight * ( index > count ? index - count : index )
95+ }
96+ return top ;
97+ }
98+
9099export function show ( id ) {
91100 const select = Data . get ( id )
92101 if ( select ) {
@@ -122,20 +131,26 @@ export function dispose(id) {
122131}
123132
124133function scrollToActive ( el , activeItem ) {
125- if ( ! activeItem ) {
126- activeItem = el . querySelector ( '.dropdown-item.active' )
127- }
134+ const virtualEl = el . querySelector ( '.dropdown-virtual' ) ;
135+
136+ activeItem ??= el . querySelector ( '.dropdown-item.active' )
128137
129138 if ( activeItem ) {
130139 const innerHeight = getInnerHeight ( el )
131140 const itemHeight = getHeight ( activeItem ) ;
132141 const index = indexOf ( el , activeItem )
133142 const margin = itemHeight * index - ( innerHeight - itemHeight ) / 2 ;
143+ const hehavior = el . getAttribute ( 'data-bb-scroll-behavior' ) ?? 'smooth' ;
144+
145+ const search = el . querySelector ( '.search' ) ;
146+ if ( search . classList . contains ( 'show' ) ) {
147+
148+ }
134149 if ( margin >= 0 ) {
135- el . scrollTo ( 0 , margin ) ;
150+ el . scrollTo ( { top : margin , left : 0 , behavior : hehavior } ) ;
136151 }
137152 else {
138- el . scrollTo ( 0 , 0 ) ;
153+ el . scrollTo ( { top : margin , left : 0 , behavior : hehavior } ) ;
139154 }
140155 }
141156}
0 commit comments