Skip to content

Commit

Permalink
fix(cdk/overlay): avoid having to manually load structural styles
Browse files Browse the repository at this point in the history
Changes the overlay so it loads its structural styles automatically, instead of requiring the user to do it.

BREAKING CHANGE:
* The overlay stays are now loaded slightly later than before which can change their specificity. You may have to update any overlay style overrides.
  • Loading branch information
crisbeto committed Aug 25, 2024
1 parent 855ed49 commit df21d2b
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/cdk/overlay/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ ng_module(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
assets = [
":overlay-prebuilt.css",
],
deps = [
"//src:dev_mode_types",
"//src/cdk/bidi",
"//src/cdk/coercion",
"//src/cdk/keycodes",
"//src/cdk/platform",
"//src/cdk/portal",
"//src/cdk/private",
"//src/cdk/scrolling",
"@npm//@angular/common",
"@npm//@angular/core",
Expand Down
28 changes: 15 additions & 13 deletions src/cdk/overlay/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,24 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
-webkit-tap-highlight-color: transparent;
transition: opacity $backdrop-animation-duration $backdrop-animation-timing-function;
opacity: 0;
}

.cdk-overlay-backdrop-showing {
opacity: 1;

&.cdk-overlay-backdrop-showing {
opacity: 1;

// Note that we can't import and use the `high-contrast` mixin from `_a11y.scss`, because
// this file will be copied to the top-level `cdk` package when putting together the files
// for npm. Any relative import paths we use here will become invalid once the file is copied.
.cdk-high-contrast-active & {
// In high contrast mode the rgba background will become solid
// so we need to fall back to making it opaque using `opacity`.
opacity: 0.6;
}
// Note that we can't import and use the `high-contrast` mixin from `_a11y.scss`, because
// this file will be copied to the top-level `cdk` package when putting together the files
// for npm. Any relative import paths we use here will become invalid once the file is copied.
.cdk-high-contrast-active & {
// In high contrast mode the rgba background will become solid
// so we need to fall back to making it opaque using `opacity`.
opacity: 0.6;
}
}

.cdk-overlay-dark-backdrop {
background: $overlay-backdrop-color;
// Add a CSS variable to make this easier to override.
background: var(--cdk-overlay-backdrop-dark-color, $overlay-backdrop-color);
}

.cdk-overlay-transparent-backdrop {
Expand All @@ -105,7 +106,8 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default;
// capturing the user's mouse scroll events. Since we also can't use something like
// `rgba(0, 0, 0, 0)`, we work around the inconsistency by not setting the background at
// all and using `opacity` to make the element transparent.
&.cdk-overlay-backdrop-showing {
&.cdk-overlay-backdrop-showing,
.cdk-high-contrast-active & {
opacity: 0;
visibility: visible;
}
Expand Down
1 change: 1 addition & 0 deletions src/cdk/overlay/fullscreen-overlay-container.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('FullscreenOverlayContainer', () => {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
fakeDocument = {
body: document.body,
head: document.head,
fullscreenElement: document.createElement('div'),
fullscreenEnabled: true,
addEventListener: (eventName: string, listener: EventListener) => {
Expand Down
29 changes: 28 additions & 1 deletion src/cdk/overlay/overlay-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,34 @@
*/

import {DOCUMENT} from '@angular/common';
import {Inject, Injectable, OnDestroy} from '@angular/core';
import {
Inject,
Injectable,
OnDestroy,
Component,
ChangeDetectionStrategy,
ViewEncapsulation,
inject,
} from '@angular/core';
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
import {Platform, _isTestEnvironment} from '@angular/cdk/platform';

@Component({
template: '',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
standalone: true,
styleUrl: 'overlay-prebuilt.css',
host: {'cdk-overlay-style-loader': ''},
})
export class _CdkOverlayStyleLoader {}

/** Container inside which all overlays will render. */
@Injectable({providedIn: 'root'})
export class OverlayContainer implements OnDestroy {
protected _containerElement: HTMLElement;
protected _document: Document;
protected _styleLoader = inject(_CdkPrivateStyleLoader);

constructor(
@Inject(DOCUMENT) document: any,
Expand All @@ -34,6 +54,8 @@ export class OverlayContainer implements OnDestroy {
* @returns the container element
*/
getContainerElement(): HTMLElement {
this._loadStyles();

if (!this._containerElement) {
this._createContainer();
}
Expand Down Expand Up @@ -84,4 +106,9 @@ export class OverlayContainer implements OnDestroy {
this._document.body.appendChild(container);
this._containerElement = container;
}

/** Loads the structural styles necessary for the overlay to work. */
protected _loadStyles(): void {
this._styleLoader.load(_CdkOverlayStyleLoader);
}
}
9 changes: 8 additions & 1 deletion src/cdk/overlay/overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ import {
ANIMATION_MODULE_TYPE,
Optional,
EnvironmentInjector,
inject,
} from '@angular/core';
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
import {OverlayKeyboardDispatcher} from './dispatchers/overlay-keyboard-dispatcher';
import {OverlayOutsideClickDispatcher} from './dispatchers/overlay-outside-click-dispatcher';
import {OverlayConfig} from './overlay-config';
import {OverlayContainer} from './overlay-container';
import {_CdkOverlayStyleLoader, OverlayContainer} from './overlay-container';
import {OverlayRef} from './overlay-ref';
import {OverlayPositionBuilder} from './position/overlay-position-builder';
import {ScrollStrategyOptions} from './scroll/index';
Expand All @@ -45,6 +47,7 @@ let nextUniqueId = 0;
@Injectable({providedIn: 'root'})
export class Overlay {
private _appRef: ApplicationRef;
private _styleLoader = inject(_CdkPrivateStyleLoader);

constructor(
/** Scrolling strategies that can be used when creating an overlay. */
Expand All @@ -68,6 +71,10 @@ export class Overlay {
* @returns Reference to the created overlay.
*/
create(config?: OverlayConfig): OverlayRef {
// This is done in the overlay container as well, but we have it here
// since it's common to mock out the overlay container in tests.
this._styleLoader.load(_CdkOverlayStyleLoader);

const host = this._createHostElement();
const pane = this._createPaneElement(host);
const portalOutlet = this._createPortalOutlet(pane);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Component, inject} from '@angular/core';
import {Overlay} from '@angular/cdk/overlay';
import {Overlay, OverlayContainer} from '@angular/cdk/overlay';
import {ScrollingModule} from '@angular/cdk/scrolling';

@Component({
Expand All @@ -11,4 +11,9 @@ import {ScrollingModule} from '@angular/cdk/scrolling';
})
export class BlockScrollStrategyE2E {
scrollStrategy = inject(Overlay).scrollStrategies.block();

constructor() {
// This loads the structural styles for the test.
inject(OverlayContainer).getContainerElement();
}
}
1 change: 0 additions & 1 deletion src/material/core/_core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
}

@include cdk.a11y-visually-hidden();
@include cdk.overlay();
@include cdk.text-field-autosize();
@include cdk.text-field-autofill();
@include private.structural-styling('mat');
Expand Down
4 changes: 4 additions & 0 deletions tools/public_api_guard/cdk/overlay.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
```ts

import { _CdkPrivateStyleLoader } from '@angular/cdk/private';
import { CdkScrollable } from '@angular/cdk/scrolling';
import { ComponentFactoryResolver } from '@angular/core';
import { ComponentPortal } from '@angular/cdk/portal';
Expand Down Expand Up @@ -303,11 +304,14 @@ export class OverlayContainer implements OnDestroy {
// (undocumented)
protected _document: Document;
getContainerElement(): HTMLElement;
protected _loadStyles(): void;
// (undocumented)
ngOnDestroy(): void;
// (undocumented)
protected _platform: Platform;
// (undocumented)
protected _styleLoader: _CdkPrivateStyleLoader;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<OverlayContainer, never>;
// (undocumented)
static ɵprov: i0.ɵɵInjectableDeclaration<OverlayContainer>;
Expand Down

0 comments on commit df21d2b

Please sign in to comment.