@@ -23,14 +23,17 @@ import {FakeViewportRuler} from '../core/overlay/position/fake-viewport-ruler';
23
23
import { MdAutocomplete } from './autocomplete' ;
24
24
import { MdInputContainer } from '../input/input-container' ;
25
25
import { Observable } from 'rxjs/Observable' ;
26
+ import { Subject } from 'rxjs/Subject' ;
26
27
import { dispatchFakeEvent } from '../core/testing/dispatch-events' ;
27
28
import { typeInElement } from '../core/testing/type-in-element' ;
29
+ import { ScrollDispatcher } from '../core/overlay/scroll/scroll-dispatcher' ;
28
30
29
31
import 'rxjs/add/operator/map' ;
30
32
31
33
describe ( 'MdAutocomplete' , ( ) => {
32
34
let overlayContainerElement : HTMLElement ;
33
35
let dir : LayoutDirection ;
36
+ let scrolledSubject = new Subject ( ) ;
34
37
35
38
beforeEach ( async ( ( ) => {
36
39
dir = 'ltr' ;
@@ -52,6 +55,8 @@ describe('MdAutocomplete', () => {
52
55
providers : [
53
56
{ provide : OverlayContainer , useFactory : ( ) => {
54
57
overlayContainerElement = document . createElement ( 'div' ) ;
58
+ overlayContainerElement . classList . add ( 'cdk-overlay-container' ) ;
59
+
55
60
document . body . appendChild ( overlayContainerElement ) ;
56
61
57
62
// remove body padding to keep consistent cross-browser
@@ -63,7 +68,12 @@ describe('MdAutocomplete', () => {
63
68
{ provide : Dir , useFactory : ( ) => {
64
69
return { value : dir } ;
65
70
} } ,
66
- { provide : ViewportRuler , useClass : FakeViewportRuler }
71
+ { provide : ViewportRuler , useClass : FakeViewportRuler } ,
72
+ { provide : ScrollDispatcher , useFactory : ( ) => {
73
+ return { scrolled : ( delay : number , callback : ( ) => any ) => {
74
+ return scrolledSubject . asObservable ( ) . subscribe ( callback ) ;
75
+ } } ;
76
+ } }
67
77
]
68
78
} ) ;
69
79
@@ -925,6 +935,29 @@ describe('MdAutocomplete', () => {
925
935
. toEqual ( 'below' , `Expected autocomplete positionY to default to below.` ) ;
926
936
} ) ;
927
937
938
+ it ( 'should reposition the panel on scroll' , ( ) => {
939
+ const spacer = document . createElement ( 'div' ) ;
940
+
941
+ spacer . style . height = '1000px' ;
942
+ document . body . appendChild ( spacer ) ;
943
+
944
+ fixture . componentInstance . trigger . openPanel ( ) ;
945
+ fixture . detectChanges ( ) ;
946
+
947
+ window . scroll ( 0 , 100 ) ;
948
+ scrolledSubject . next ( ) ;
949
+ fixture . detectChanges ( ) ;
950
+
951
+ const inputBottom = input . getBoundingClientRect ( ) . bottom ;
952
+ const panel = overlayContainerElement . querySelector ( '.mat-autocomplete-panel' ) ;
953
+ const panelTop = panel . getBoundingClientRect ( ) . top ;
954
+
955
+ expect ( ( inputBottom + 6 ) . toFixed ( 1 ) ) . toEqual ( panelTop . toFixed ( 1 ) ,
956
+ 'Expected panel top to match input bottom after scrolling.' ) ;
957
+
958
+ document . body . removeChild ( spacer ) ;
959
+ } ) ;
960
+
928
961
it ( 'should fall back to above position if panel cannot fit below' , ( ) => {
929
962
// Push the autocomplete trigger down so it won't have room to open "below"
930
963
input . style . top = '600px' ;
0 commit comments