@@ -53,6 +53,7 @@ export class MultipleSelectInstance {
53
53
protected selectAllName = '' ;
54
54
protected selectGroupName = '' ;
55
55
protected selectItemName = '' ;
56
+ protected scrolledByMouse = false ;
56
57
protected openDelayTimer : NodeJS . Timeout | undefined ;
57
58
58
59
protected updateDataStart ?: number ;
@@ -538,10 +539,11 @@ export class MultipleSelectInstance {
538
539
if ( this . options . infiniteScroll ) {
539
540
rows . push ( {
540
541
tagName : 'li' ,
541
- props : { className : 'ms-infinite-option' , role : 'option' , dataset : { key : 'infinite' } } ,
542
+ props : { className : 'ms-infinite-option' , role : 'option' } ,
542
543
} ) ;
543
544
}
544
545
546
+ // add a "No Results" option that is hidden by default
545
547
rows . push ( { tagName : 'li' , props : { className : 'ms-no-results' , textContent : this . formatNoMatchesFound ( ) } } ) ;
546
548
547
549
return rows ;
@@ -1000,7 +1002,7 @@ export class MultipleSelectInstance {
1000
1002
'mouseover' ,
1001
1003
( ( e : MouseEvent & { target : HTMLDivElement | HTMLLIElement } ) => {
1002
1004
const liElm = ( e . target . closest ( '.ms-select-all' ) || e . target . closest ( 'li' ) ) as HTMLLIElement ;
1003
- if ( this . dropElm . contains ( liElm ) ) {
1005
+ if ( this . dropElm . contains ( liElm ) && this . scrolledByMouse ) {
1004
1006
const optionElms = this . dropElm ?. querySelectorAll < HTMLLIElement > ( OPTIONS_LIST_SELECTOR ) || [ ] ;
1005
1007
const newIdx = Array . from ( optionElms ) . findIndex ( el => el . dataset . key === liElm . dataset . key ) ;
1006
1008
if ( this . _currentHighlightIndex !== newIdx && ! liElm . classList . contains ( 'disabled' ) ) {
@@ -1083,19 +1085,26 @@ export class MultipleSelectInstance {
1083
1085
* Checks if user reached the end of the list through mouse scrolling and/or arrow down,
1084
1086
* then scroll back to the top whenever that happens.
1085
1087
*/
1086
- protected infiniteScrollHandler ( e : MouseEvent & { target : HTMLElement } ) {
1087
- if ( e . target && this . ulElm ) {
1088
- const scrollPos = e . target . scrollTop + e . target . clientHeight ;
1088
+ protected infiniteScrollHandler ( e : ( MouseEvent & { target : HTMLElement } ) | null , idx ?: number , fullCount ?: number ) {
1089
+ let needHighlightRecalc = false ;
1089
1090
1091
+ if ( e ?. target && this . ulElm && this . scrolledByMouse ) {
1092
+ const scrollPos = e . target . scrollTop + e . target . clientHeight ;
1090
1093
if ( scrollPos === this . ulElm . scrollHeight ) {
1091
- if ( this . virtualScroll ) {
1092
- this . initListItems ( ) ;
1093
- } else {
1094
- this . ulElm . scrollTop = 0 ;
1095
- }
1096
- this . _currentHighlightIndex = 0 ;
1097
- this . highlightCurrentOption ( ) ;
1094
+ needHighlightRecalc = true ;
1098
1095
}
1096
+ } else if ( idx !== undefined && idx + 1 === fullCount ) {
1097
+ needHighlightRecalc = true ;
1098
+ }
1099
+
1100
+ if ( needHighlightRecalc && this . ulElm ) {
1101
+ if ( this . virtualScroll ) {
1102
+ this . initListItems ( ) ;
1103
+ } else {
1104
+ this . ulElm . scrollTop = 0 ;
1105
+ }
1106
+ this . _currentHighlightIndex = 0 ;
1107
+ this . highlightCurrentOption ( ) ;
1099
1108
}
1100
1109
}
1101
1110
@@ -1236,8 +1245,11 @@ export class MultipleSelectInstance {
1236
1245
this . _currentSelectedElm = currentOption ;
1237
1246
1238
1247
// Scroll the current option into view
1248
+ // use a global flag to differentiate scroll by mouse or by scrollIntoView
1249
+ this . scrolledByMouse = false ;
1239
1250
currentOption . scrollIntoView ( { block : 'nearest' } ) ;
1240
1251
this . changeCurrentOptionHighlight ( currentOption ) ;
1252
+ setTimeout ( ( ) => ( this . scrolledByMouse = true ) , 10 ) ;
1241
1253
}
1242
1254
}
1243
1255
}
@@ -1255,11 +1267,15 @@ export class MultipleSelectInstance {
1255
1267
1256
1268
protected moveHighlightDown ( ) {
1257
1269
const optionElms = this . dropElm ?. querySelectorAll < HTMLLIElement > ( OPTIONS_LIST_SELECTOR ) || [ ] ;
1258
- if ( this . _currentHighlightIndex < optionElms . length - 1 ) {
1270
+ const domOptionsCount = optionElms . length ;
1271
+
1272
+ if ( this . _currentHighlightIndex < domOptionsCount - 1 ) {
1259
1273
this . _currentHighlightIndex ++ ;
1260
1274
if ( optionElms [ this . _currentHighlightIndex ] ?. classList . contains ( 'disabled' ) ) {
1261
1275
this . moveHighlightDown ( ) ;
1262
1276
}
1277
+ } else if ( this . options . infiniteScroll ) {
1278
+ this . infiniteScrollHandler ( null , this . _currentHighlightIndex , domOptionsCount ) ;
1263
1279
}
1264
1280
this . highlightCurrentOption ( ) ;
1265
1281
}
0 commit comments