@@ -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 ( ) {
@@ -106,7 +106,7 @@ export class ConnectedPositionStrategy implements PositionStrategy {
106
106
// If the overlay in the calculated position fits on-screen, put it there and we're done.
107
107
if ( overlayPoint . fitsInViewport ) {
108
108
this . _setElementPosition ( element , overlayPoint ) ;
109
- const isClipped = this . isConnectedToElementClipped ( ) ;
109
+ const isClipped = this . isOverlayElementClipped ( element ) ;
110
110
this . _onPositionChange . next ( new ConnectedOverlayPositionChange ( pos , isClipped ) ) ;
111
111
return Promise . resolve ( null ) ;
112
112
} else if ( ! fallbackPoint || fallbackPoint . visibleArea < overlayPoint . visibleArea ) {
@@ -262,6 +262,21 @@ export class ConnectedPositionStrategy implements PositionStrategy {
262
262
return { x, y, fitsInViewport, visibleArea} ;
263
263
}
264
264
265
+ /** Whether the overlay element is clipped out of view of one of the scrollable containers. */
266
+ private isOverlayElementClipped ( element : HTMLElement ) : boolean {
267
+ const elementBounds = this . _getElementBounds ( element ) ;
268
+ return this . scrollables . some ( ( scrollable : Scrollable ) => {
269
+ const scrollingContainerBounds = this . _getElementBounds ( scrollable . getElementRef ( ) . nativeElement ) ;
270
+
271
+ const clippedAbove = elementBounds . top < scrollingContainerBounds . top ;
272
+ const clippedBelow = elementBounds . bottom > scrollingContainerBounds . bottom ;
273
+ const clippedLeft = elementBounds . left < scrollingContainerBounds . left ;
274
+ const clippedRight = elementBounds . right > scrollingContainerBounds . right ;
275
+
276
+ return clippedAbove || clippedBelow || clippedLeft || clippedRight ;
277
+ } ) ;
278
+ }
279
+
265
280
/**
266
281
* Physically positions the overlay element to the given coordinate.
267
282
* @param element
@@ -272,8 +287,8 @@ export class ConnectedPositionStrategy implements PositionStrategy {
272
287
element . style . top = overlayPoint . y + 'px' ;
273
288
}
274
289
275
- private _getElementBounds ( element : ElementRef ) : ElementBoundingPositions {
276
- const boundingClientRect = element . nativeElement . getBoundingClientRect ( ) ;
290
+ private _getElementBounds ( element : HTMLElement ) : ElementBoundingPositions {
291
+ const boundingClientRect = element . getBoundingClientRect ( ) ;
277
292
return {
278
293
top : boundingClientRect . top ,
279
294
right : boundingClientRect . left + boundingClientRect . width ,
0 commit comments