@@ -24,9 +24,22 @@ import {dispatchFakeEvent} from '../core/testing/dispatch-events';
24
24
import { wrappedErrorMessage } from '../core/testing/wrapped-error-message' ;
25
25
26
26
27
+ class FakeViewportRuler {
28
+ getViewportRect ( ) {
29
+ return {
30
+ left : 0 , top : 0 , width : 1014 , height : 686 , bottom : 686 , right : 1014
31
+ } ;
32
+ }
33
+
34
+ getViewportScrollPosition ( ) {
35
+ return { top : 0 , left : 0 } ;
36
+ }
37
+ }
38
+
27
39
describe ( 'MdSelect' , ( ) => {
28
40
let overlayContainerElement : HTMLElement ;
29
41
let dir : { value : 'ltr' | 'rtl' } ;
42
+ let fakeViewportRuler = new FakeViewportRuler ( ) ;
30
43
31
44
beforeEach ( async ( ( ) => {
32
45
TestBed . configureTestingModule ( {
@@ -65,7 +78,7 @@ describe('MdSelect', () => {
65
78
{ provide : Dir , useFactory : ( ) => {
66
79
return dir = { value : 'ltr' } ;
67
80
} } ,
68
- { provide : ViewportRuler , useClass : FakeViewportRuler }
81
+ { provide : ViewportRuler , useValue : fakeViewportRuler }
69
82
]
70
83
} ) ;
71
84
@@ -882,6 +895,94 @@ describe('MdSelect', () => {
882
895
883
896
} ) ;
884
897
898
+ describe ( 'limited space to open horizontally' , ( ) => {
899
+ beforeEach ( async ( ( ) => {
900
+ select . style . position = 'absolute' ;
901
+ select . style . top = '200px' ;
902
+ } ) ) ;
903
+
904
+ it ( 'should stay within the viewport when overflowing on the left in ltr' , async ( ( ) => {
905
+ select . style . left = '-100px' ;
906
+ trigger . click ( ) ;
907
+ fixture . detectChanges ( ) ;
908
+
909
+ fixture . whenStable ( ) . then ( ( ) => {
910
+ const panelLeft = document . querySelector ( '.mat-select-panel' )
911
+ . getBoundingClientRect ( ) . left ;
912
+ expect ( panelLeft ) . toBeGreaterThan ( 0 ,
913
+ `Expected select panel to be inside the viewport in ltr.` ) ;
914
+ } ) ;
915
+ } ) ) ;
916
+
917
+ it ( 'should stay within the viewport when overflowing on the right in rtl' , async ( ( ) => {
918
+ dir . value = 'rtl' ;
919
+ select . style . left = '-100px' ;
920
+ trigger . click ( ) ;
921
+ fixture . detectChanges ( ) ;
922
+
923
+ fixture . whenStable ( ) . then ( ( ) => {
924
+ const panelLeft = document . querySelector ( '.mat-select-panel' )
925
+ . getBoundingClientRect ( ) . left ;
926
+
927
+ expect ( panelLeft ) . toBeGreaterThan ( 0 ,
928
+ `Expected select panel to be inside the viewport in rtl.` ) ;
929
+ } ) ;
930
+ } ) ) ;
931
+
932
+ it ( 'should stay within the viewport when overflowing on the right in ltr' , async ( ( ) => {
933
+ select . style . right = '-100px' ;
934
+ trigger . click ( ) ;
935
+ fixture . detectChanges ( ) ;
936
+
937
+ fixture . whenStable ( ) . then ( ( ) => {
938
+ const viewportRect = fakeViewportRuler . getViewportRect ( ) . right ;
939
+ const panelRight = document . querySelector ( '.mat-select-panel' )
940
+ . getBoundingClientRect ( ) . right ;
941
+
942
+ expect ( viewportRect - panelRight ) . toBeGreaterThan ( 0 ,
943
+ `Expected select panel to be inside the viewport in ltr.` ) ;
944
+ } ) ;
945
+ } ) ) ;
946
+
947
+ it ( 'should stay within the viewport when overflowing on the right in rtl' , async ( ( ) => {
948
+ dir . value = 'rtl' ;
949
+ select . style . right = '-100px' ;
950
+ trigger . click ( ) ;
951
+ fixture . detectChanges ( ) ;
952
+
953
+ fixture . whenStable ( ) . then ( ( ) => {
954
+ const viewportRect = fakeViewportRuler . getViewportRect ( ) . right ;
955
+ const panelRight = document . querySelector ( '.mat-select-panel' )
956
+ . getBoundingClientRect ( ) . right ;
957
+
958
+ expect ( viewportRect - panelRight ) . toBeGreaterThan ( 0 ,
959
+ `Expected select panel to be inside the viewport in rtl.` ) ;
960
+ } ) ;
961
+ } ) ) ;
962
+
963
+ it ( 'should keep the position within the viewport on repeat openings' , async ( ( ) => {
964
+ select . style . left = '-100px' ;
965
+ trigger . click ( ) ;
966
+ fixture . detectChanges ( ) ;
967
+
968
+ let panelLeft = document . querySelector ( '.mat-select-panel' ) . getBoundingClientRect ( ) . left ;
969
+
970
+ expect ( panelLeft ) . toBeGreaterThan ( 0 , `Expected select panel to be inside the viewport.` ) ;
971
+
972
+ fixture . componentInstance . select . close ( ) ;
973
+ fixture . detectChanges ( ) ;
974
+
975
+ fixture . whenStable ( ) . then ( ( ) => {
976
+ trigger . click ( ) ;
977
+ fixture . detectChanges ( ) ;
978
+ panelLeft = document . querySelector ( '.mat-select-panel' ) . getBoundingClientRect ( ) . left ;
979
+
980
+ expect ( panelLeft ) . toBeGreaterThan ( 0 ,
981
+ `Expected select panel continue being inside the viewport.` ) ;
982
+ } ) ;
983
+ } ) ) ;
984
+ } ) ;
985
+
885
986
describe ( 'when scrolled' , ( ) => {
886
987
887
988
// Need to set the scrollTop two different ways to support
@@ -1030,8 +1131,8 @@ describe('MdSelect', () => {
1030
1131
trigger = multiFixture . debugElement . query ( By . css ( '.mat-select-trigger' ) ) . nativeElement ;
1031
1132
select = multiFixture . debugElement . query ( By . css ( 'md-select' ) ) . nativeElement ;
1032
1133
1033
- select . style . marginLeft = '20px ' ;
1034
- select . style . marginRight = '20px ' ;
1134
+ select . style . marginLeft = '60px ' ;
1135
+ select . style . marginRight = '60px ' ;
1035
1136
} ) ;
1036
1137
1037
1138
it ( 'should adjust for the checkbox in ltr' , ( ) => {
@@ -1956,16 +2057,3 @@ class SelectWithPlainTabindex { }
1956
2057
`
1957
2058
} )
1958
2059
class SelectEarlyAccessSibling { }
1959
-
1960
-
1961
- class FakeViewportRuler {
1962
- getViewportRect ( ) {
1963
- return {
1964
- left : 0 , top : 0 , width : 1014 , height : 686 , bottom : 686 , right : 1014
1965
- } ;
1966
- }
1967
-
1968
- getViewportScrollPosition ( ) {
1969
- return { top : 0 , left : 0 } ;
1970
- }
1971
- }
0 commit comments