1
- import { Component , HostListener } from '@angular/core' ;
1
+ import { Component , ElementRef , HostListener , ViewChild } from '@angular/core' ;
2
2
import { Subject } from 'rxjs' ;
3
3
4
4
@Component ( {
5
5
template : `
6
6
<ul
7
7
*ngIf="choices?.length > 0"
8
+ #dropdownMenu
8
9
class="dropdown-menu"
9
10
[style.top.px]="position?.top"
10
11
[style.left.px]="position?.left">
11
- <li
12
+ <li
12
13
*ngFor="let choice of choices"
13
14
[class.active]="activeChoice === choice">
14
15
<a
@@ -21,15 +22,16 @@ import { Subject } from 'rxjs';
21
22
` ,
22
23
styles : [
23
24
`
24
- .dropdown-menu {
25
- display: block;
26
- max-height: 200px;
27
- overflow-y: auto;
28
- }
29
- `
25
+ .dropdown-menu {
26
+ display: block;
27
+ max-height: 200px;
28
+ overflow-y: auto;
29
+ }
30
+ `
30
31
]
31
32
} )
32
33
export class TextInputAutocompleteMenuComponent {
34
+ @ViewChild ( 'dropdownMenu' ) dropdownMenuElement : ElementRef < HTMLUListElement > ;
33
35
position : { top : number ; left : number } ;
34
36
selectChoice = new Subject ( ) ;
35
37
activeChoice : any ;
@@ -54,7 +56,7 @@ export class TextInputAutocompleteMenuComponent {
54
56
event . preventDefault ( ) ;
55
57
const index = this . choices . indexOf ( this . activeChoice ) ;
56
58
if ( this . choices [ index + 1 ] ) {
57
- this . activeChoice = this . _choices [ index + 1 ] ;
59
+ this . scrollToChoice ( index + 1 ) ;
58
60
}
59
61
}
60
62
@@ -63,7 +65,7 @@ export class TextInputAutocompleteMenuComponent {
63
65
event . preventDefault ( ) ;
64
66
const index = this . choices . indexOf ( this . activeChoice ) ;
65
67
if ( this . choices [ index - 1 ] ) {
66
- this . activeChoice = this . _choices [ index - 1 ] ;
68
+ this . scrollToChoice ( index - 1 ) ;
67
69
}
68
70
}
69
71
@@ -74,4 +76,18 @@ export class TextInputAutocompleteMenuComponent {
74
76
this . selectChoice . next ( this . activeChoice ) ;
75
77
}
76
78
}
79
+
80
+ private scrollToChoice ( index : number ) {
81
+ this . activeChoice = this . _choices [ index ] ;
82
+ if ( this . dropdownMenuElement ) {
83
+ const ulPosition = this . dropdownMenuElement . nativeElement . getBoundingClientRect ( ) ;
84
+ const li = this . dropdownMenuElement . nativeElement . children [ index ] ;
85
+ const liPosition = li . getBoundingClientRect ( ) ;
86
+ if ( liPosition . top < ulPosition . top ) {
87
+ li . scrollIntoView ( ) ;
88
+ } else if ( liPosition . bottom > ulPosition . bottom ) {
89
+ li . scrollIntoView ( false ) ;
90
+ }
91
+ }
92
+ }
77
93
}
0 commit comments