@@ -35,7 +35,7 @@ export class ConnectedPositionStrategy implements PositionStrategy {
35
35
private _offsetY : number = 0 ;
36
36
37
37
/** The Scrollable containers that may cause the overlay's connectedTo element to be clipped */
38
- private scrollables : Scrollable [ ] ;
38
+ private scrollables : Scrollable [ ] = [ ] ;
39
39
40
40
/** Whether the we're dealing with an RTL context */
41
41
get _isRtl ( ) {
@@ -102,7 +102,7 @@ export class ConnectedPositionStrategy implements PositionStrategy {
102
102
// If the overlay in the calculated position fits on-screen, put it there and we're done.
103
103
if ( overlayPoint . fitsInViewport ) {
104
104
this . _setElementPosition ( element , overlayPoint ) ;
105
- const isClipped = this . isConnectedToElementClipped ( ) ;
105
+ const isClipped = this . isOverlayElementClipped ( element ) ;
106
106
this . _onPositionChange . next ( new ConnectedOverlayPositionChange ( pos , isClipped ) ) ;
107
107
return Promise . resolve ( null ) ;
108
108
} else if ( ! fallbackPoint || fallbackPoint . visibleArea < overlayPoint . visibleArea ) {
@@ -243,6 +243,21 @@ export class ConnectedPositionStrategy implements PositionStrategy {
243
243
return { x, y, fitsInViewport, visibleArea} ;
244
244
}
245
245
246
+ /** Whether the overlay element is clipped out of view of one of the scrollable containers. */
247
+ private isOverlayElementClipped ( element : HTMLElement ) : boolean {
248
+ const elementBounds = this . _getElementBounds ( element ) ;
249
+ return this . scrollables . some ( ( scrollable : Scrollable ) => {
250
+ const scrollingContainerBounds = this . _getElementBounds ( scrollable . getElementRef ( ) . nativeElement ) ;
251
+
252
+ const clippedAbove = elementBounds . top < scrollingContainerBounds . top ;
253
+ const clippedBelow = elementBounds . bottom > scrollingContainerBounds . bottom ;
254
+ const clippedLeft = elementBounds . left < scrollingContainerBounds . left ;
255
+ const clippedRight = elementBounds . right > scrollingContainerBounds . right ;
256
+
257
+ return clippedAbove || clippedBelow || clippedLeft || clippedRight ;
258
+ } ) ;
259
+ }
260
+
246
261
/**
247
262
* Physically positions the overlay element to the given coordinate.
248
263
* @param element
@@ -253,8 +268,8 @@ export class ConnectedPositionStrategy implements PositionStrategy {
253
268
element . style . top = overlayPoint . y + 'px' ;
254
269
}
255
270
256
- private _getElementBounds ( element : ElementRef ) : ElementBoundingPositions {
257
- const boundingClientRect = element . nativeElement . getBoundingClientRect ( ) ;
271
+ private _getElementBounds ( element : HTMLElement ) : ElementBoundingPositions {
272
+ const boundingClientRect = element . getBoundingClientRect ( ) ;
258
273
return {
259
274
top : boundingClientRect . top ,
260
275
right : boundingClientRect . left + boundingClientRect . width ,
0 commit comments