diff --git a/src/cdk/overlay/_index.scss b/src/cdk/overlay/_index.scss index 714cf2979858..db174855c55b 100644 --- a/src/cdk/overlay/_index.scss +++ b/src/cdk/overlay/_index.scss @@ -195,7 +195,7 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; position: fixed; pointer-events: none; white-space: normal; - line-height: normal; + color: inherit; text-decoration: none; // These are important so the overlay can be measured before it's fully inserted. @@ -206,6 +206,10 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; // with `align-self` can break the positioning (see #29809). inset: auto; + // Some older versions of Chrome won't render the popover properly without these. + top: 0; + left: 0; + // For the time being we're using our `.cdk-overlay-backdrop` element instead of the native one. &::backdrop { display: none; @@ -213,6 +217,7 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; .cdk-overlay-backdrop { position: fixed; + z-index: auto; } } } diff --git a/src/cdk/overlay/overlay-config.ts b/src/cdk/overlay/overlay-config.ts index c382a1a5fe02..c49ed9c1eb2b 100644 --- a/src/cdk/overlay/overlay-config.ts +++ b/src/cdk/overlay/overlay-config.ts @@ -65,7 +65,7 @@ export class OverlayConfig { * Whether the overlay should be rendered as a native popover element, * rather than placing it inside of the overlay container. */ - usePopover?: boolean = false; + usePopover?: boolean; constructor(config?: OverlayConfig) { if (config) { diff --git a/src/cdk/overlay/overlay-directives.ts b/src/cdk/overlay/overlay-directives.ts index 15bb05889834..9cb58cc99700 100644 --- a/src/cdk/overlay/overlay-directives.ts +++ b/src/cdk/overlay/overlay-directives.ts @@ -253,7 +253,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges { /** Whether the connected overlay should be rendered inside a popover element or the overlay container. */ @Input({alias: 'cdkConnectedOverlayUsePopover'}) - usePopover: FlexibleOverlayPopoverLocation | null = null; + usePopover: FlexibleOverlayPopoverLocation | null = 'global'; /** Whether the overlay should match the trigger's width. */ @Input({alias: 'cdkConnectedOverlayMatchWidth', transform: booleanAttribute}) diff --git a/src/cdk/overlay/overlay-ref.ts b/src/cdk/overlay/overlay-ref.ts index 5d4792606890..59971cf7b28b 100644 --- a/src/cdk/overlay/overlay-ref.ts +++ b/src/cdk/overlay/overlay-ref.ts @@ -417,7 +417,12 @@ export class OverlayRef implements PortalOutlet { } if (this._config.usePopover) { - this._host.showPopover(); + // We need the try/catch because the browser will throw if the + // host or any of the parents are outside the DOM. Also note + // the string access which is there for compatibility with Closure. + try { + this._host['showPopover'](); + } catch {} } } diff --git a/src/cdk/overlay/overlay.spec.ts b/src/cdk/overlay/overlay.spec.ts index 20fcb3f9d5b1..400a7d9a9285 100644 --- a/src/cdk/overlay/overlay.spec.ts +++ b/src/cdk/overlay/overlay.spec.ts @@ -141,9 +141,9 @@ describe('Overlay', () => { expect(overlayContainerElement.textContent).toBe(''); }); - it('should ensure that the most-recently-attached overlay is on top', () => { - let pizzaOverlayRef = createOverlayRef(injector); - let cakeOverlayRef = createOverlayRef(injector); + it('should ensure that the most-recently-attached overlay is on top when popovers are disabled', () => { + let pizzaOverlayRef = createOverlayRef(injector, {usePopover: false}); + let cakeOverlayRef = createOverlayRef(injector, {usePopover: false}); pizzaOverlayRef.attach(componentPortal); cakeOverlayRef.attach(templatePortal); @@ -850,7 +850,7 @@ describe('Overlay', () => { }); it('should insert the backdrop before the overlay host in the DOM order', () => { - const overlayRef = createOverlayRef(injector, config); + const overlayRef = createOverlayRef(injector, {...config, usePopover: false}); overlayRef.attach(componentPortal); viewContainerFixture.detectChanges(); diff --git a/src/cdk/overlay/overlay.ts b/src/cdk/overlay/overlay.ts index 6b739a0a57a4..3a909dfdb442 100644 --- a/src/cdk/overlay/overlay.ts +++ b/src/cdk/overlay/overlay.ts @@ -52,9 +52,13 @@ export function createOverlayRef(injector: Injector, config?: OverlayConfig): Ov injector.get(RendererFactory2).createRenderer(null, null); const overlayConfig = new OverlayConfig(config); - overlayConfig.direction = overlayConfig.direction || directionality.value; - overlayConfig.usePopover = !!overlayConfig?.usePopover && 'showPopover' in doc.body; + + if (!('showPopover' in doc.body)) { + overlayConfig.usePopover = false; + } else { + overlayConfig.usePopover = config?.usePopover ?? true; + } const pane = doc.createElement('div'); const host = doc.createElement('div'); diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts index 4a49f6b30f2b..11b7326fb779 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts @@ -140,6 +140,7 @@ describe('FlexibleConnectedPositionStrategy', () => { overlayContainer.getContainerElement().style.top = '-100px'; attachOverlay({ + usePopover: false, positionStrategy: createFlexibleConnectedPositionStrategy(injector, originElement) .withFlexibleDimensions(false) .withPush(false) @@ -2642,7 +2643,7 @@ describe('FlexibleConnectedPositionStrategy', () => { attachOverlay({positionStrategy}); expect(overlayRef.hostElement.style.left).toBeTruthy(); - expect(overlayRef.hostElement.style.right).toBeFalsy(); + expect(overlayRef.hostElement.style.right).toBe('auto'); }); it('should use `right` when positioning an element at the end', () => { @@ -2658,7 +2659,7 @@ describe('FlexibleConnectedPositionStrategy', () => { attachOverlay({positionStrategy}); expect(overlayRef.hostElement.style.right).toBeTruthy(); - expect(overlayRef.hostElement.style.left).toBeFalsy(); + expect(overlayRef.hostElement.style.left).toBe('auto'); }); }); @@ -2679,7 +2680,7 @@ describe('FlexibleConnectedPositionStrategy', () => { }); expect(overlayRef.hostElement.style.right).toBeTruthy(); - expect(overlayRef.hostElement.style.left).toBeFalsy(); + expect(overlayRef.hostElement.style.left).toBe('auto'); }); it('should use `left` when positioning an element at the end', () => { @@ -2695,7 +2696,7 @@ describe('FlexibleConnectedPositionStrategy', () => { attachOverlay({positionStrategy, direction: 'rtl'}); expect(overlayRef.hostElement.style.left).toBeTruthy(); - expect(overlayRef.hostElement.style.right).toBeFalsy(); + expect(overlayRef.hostElement.style.right).toBe('auto'); }); }); @@ -2713,7 +2714,7 @@ describe('FlexibleConnectedPositionStrategy', () => { attachOverlay({positionStrategy}); expect(overlayRef.hostElement.style.top).toBeTruthy(); - expect(overlayRef.hostElement.style.bottom).toBeFalsy(); + expect(overlayRef.hostElement.style.bottom).toBe('auto'); }); it('should use `bottom` when positioning at element along the bottom', () => { @@ -2729,7 +2730,7 @@ describe('FlexibleConnectedPositionStrategy', () => { attachOverlay({positionStrategy}); expect(overlayRef.hostElement.style.bottom).toBeTruthy(); - expect(overlayRef.hostElement.style.top).toBeFalsy(); + expect(overlayRef.hostElement.style.top).toBe('auto'); }); }); }); diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.ts index 8381a415d568..e70ac701d2de 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.ts @@ -923,18 +923,19 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { if (this._hasExactPosition()) { styles.top = styles.left = '0'; - styles.bottom = styles.right = styles.maxHeight = styles.maxWidth = ''; + styles.bottom = styles.right = 'auto'; + styles.maxHeight = styles.maxWidth = ''; styles.width = styles.height = '100%'; } else { const maxHeight = this._overlayRef.getConfig().maxHeight; const maxWidth = this._overlayRef.getConfig().maxWidth; - styles.height = coerceCssPixelValue(boundingBoxRect.height); - styles.top = coerceCssPixelValue(boundingBoxRect.top); - styles.bottom = coerceCssPixelValue(boundingBoxRect.bottom); styles.width = coerceCssPixelValue(boundingBoxRect.width); - styles.left = coerceCssPixelValue(boundingBoxRect.left); - styles.right = coerceCssPixelValue(boundingBoxRect.right); + styles.height = coerceCssPixelValue(boundingBoxRect.height); + styles.top = coerceCssPixelValue(boundingBoxRect.top) || 'auto'; + styles.bottom = coerceCssPixelValue(boundingBoxRect.bottom) || 'auto'; + styles.left = coerceCssPixelValue(boundingBoxRect.left) || 'auto'; + styles.right = coerceCssPixelValue(boundingBoxRect.right) || 'auto'; // Push the pane content towards the proper direction. if (position.overlayX === 'center') {