@@ -14,14 +14,17 @@ import {FakeViewportRuler} from '../core/overlay/position/fake-viewport-ruler';
14
14
import { MdAutocomplete } from './autocomplete' ;
15
15
import { MdInputContainer } from '../input/input-container' ;
16
16
import { Observable } from 'rxjs/Observable' ;
17
+ import { Subject } from 'rxjs/Subject' ;
17
18
import { dispatchFakeEvent } from '../core/testing/dispatch-events' ;
18
19
import { typeInElement } from '../core/testing/type-in-element' ;
20
+ import { ScrollDispatcher } from '../core/overlay/scroll/scroll-dispatcher' ;
19
21
20
22
import 'rxjs/add/operator/map' ;
21
23
22
24
describe ( 'MdAutocomplete' , ( ) => {
23
25
let overlayContainerElement : HTMLElement ;
24
26
let dir : LayoutDirection ;
27
+ let scrolledSubject = new Subject ( ) ;
25
28
26
29
beforeEach ( async ( ( ) => {
27
30
dir = 'ltr' ;
@@ -38,6 +41,8 @@ describe('MdAutocomplete', () => {
38
41
providers : [
39
42
{ provide : OverlayContainer , useFactory : ( ) => {
40
43
overlayContainerElement = document . createElement ( 'div' ) ;
44
+ overlayContainerElement . classList . add ( 'cdk-overlay-container' ) ;
45
+
41
46
document . body . appendChild ( overlayContainerElement ) ;
42
47
43
48
// remove body padding to keep consistent cross-browser
@@ -49,7 +54,12 @@ describe('MdAutocomplete', () => {
49
54
{ provide : Dir , useFactory : ( ) => {
50
55
return { value : dir } ;
51
56
} } ,
52
- { provide : ViewportRuler , useClass : FakeViewportRuler }
57
+ { provide : ViewportRuler , useClass : FakeViewportRuler } ,
58
+ { provide : ScrollDispatcher , useFactory : ( ) => {
59
+ return { scrolled : ( delay : number , callback : ( ) => any ) => {
60
+ return scrolledSubject . asObservable ( ) . subscribe ( callback ) ;
61
+ } } ;
62
+ } }
53
63
]
54
64
} ) ;
55
65
@@ -853,6 +863,29 @@ describe('MdAutocomplete', () => {
853
863
. toEqual ( 'below' , `Expected autocomplete positionY to default to below.` ) ;
854
864
} ) ;
855
865
866
+ it ( 'should reposition the panel on scroll' , ( ) => {
867
+ const spacer = document . createElement ( 'div' ) ;
868
+
869
+ spacer . style . height = '1000px' ;
870
+ document . body . appendChild ( spacer ) ;
871
+
872
+ fixture . componentInstance . trigger . openPanel ( ) ;
873
+ fixture . detectChanges ( ) ;
874
+
875
+ window . scroll ( 0 , 100 ) ;
876
+ scrolledSubject . next ( ) ;
877
+ fixture . detectChanges ( ) ;
878
+
879
+ const inputBottom = input . getBoundingClientRect ( ) . bottom ;
880
+ const panel = overlayContainerElement . querySelector ( '.mat-autocomplete-panel' ) ;
881
+ const panelTop = panel . getBoundingClientRect ( ) . top ;
882
+
883
+ expect ( ( inputBottom + 6 ) . toFixed ( 1 ) ) . toEqual ( panelTop . toFixed ( 1 ) ,
884
+ 'Expected panel top to match input bottom after scrolling.' ) ;
885
+
886
+ document . body . removeChild ( spacer ) ;
887
+ } ) ;
888
+
856
889
it ( 'should fall back to above position if panel cannot fit below' , ( ) => {
857
890
// Push the autocomplete trigger down so it won't have room to open "below"
858
891
input . style . top = '600px' ;
0 commit comments