feat(overlay): replace OverlayContainer themeClass w/ addClass/removeClass methods (#6975)

BREAKING CHANGE: Now that the Overlay is part of the cdk rather than Angular Material directly,
the `themeClass` property has been removed. To add a class to the
overlay for theming, you can do
```ts
overlayContainer.getContainerElement().classList.add('my-theme-class');
```
This commit is contained in:
Jeremy Elbourn
2017-09-20 16:04:41 -07:00
committed by GitHub
parent 2b0315d3a2
commit a944f6e0f2
5 changed files with 22 additions and 76 deletions
+2 -5
View File
@@ -169,7 +169,7 @@ Since certain components (e.g. menu, select, dialog, etc.) are inside of a globa
an additional step is required for those components to be affected by the theme's css class selector
(`.unicorn-dark-theme` in the example above).
To do this, you can specify a `themeClass` on the global overlay container. For the example above,
To do this, you can add the appropriate class to the global overlay container. For the example above,
this would look like:
```ts
import {OverlayContainer} from '@angular/material';
@@ -179,14 +179,11 @@ import {OverlayContainer} from '@angular/material';
})
export class UnicornCandyAppModule {
constructor(overlayContainer: OverlayContainer) {
overlayContainer.themeClass = 'unicorn-dark-theme';
overlayContainer.getContainerElement().classList.add('unicorn-dark-theme');
}
}
```
The `themeClass` of the `OverlayContainer` can be changed at any time to change the active theme
class.
#### Theming only certain components
The `angular-material-theme` mixin will output styles for [all components in the library](https://github.com/angular/material2/blob/master/src/lib/core/theming/_all-theme.scss).
If you are only using a subset of the components (or if you want to change the theme for specific
+17
View File
@@ -26,6 +26,10 @@ describe('OverlayContainer', () => {
overlayContainer = oc;
}));
afterEach(() => {
overlayContainer.ngOnDestroy();
});
it('should remove the overlay container element from the DOM on destruction', () => {
const fixture = TestBed.createComponent(TestComponentWithTemplatePortals);
@@ -43,6 +47,19 @@ describe('OverlayContainer', () => {
expect(document.querySelector('.cdk-overlay-container'))
.toBeNull('Expected the overlay container *not* to be in the DOM after destruction');
});
it('should add and remove css classes from the container element', () => {
overlayContainer.getContainerElement().classList.add('commander-shepard');
const containerElement = document.querySelector('.cdk-overlay-container')!;
expect(containerElement.classList.contains('commander-shepard'))
.toBe(true, 'Expected the overlay container to have class "commander-shepard"');
overlayContainer.getContainerElement().classList.remove('commander-shepard');
expect(containerElement.classList.contains('commander-shepard'))
.toBe(false, 'Expected the overlay container not to have class "commander-shepard"');
});
});
/** Test-bed component that contains a TempatePortal and an ElementRef. */
+1 -25
View File
@@ -17,26 +17,6 @@ import {Injectable, Optional, SkipSelf, OnDestroy} from '@angular/core';
export class OverlayContainer implements OnDestroy {
protected _containerElement: HTMLElement;
private _themeClass: string;
/**
* Base theme to be applied to all overlay-based components.
*/
get themeClass(): string { return this._themeClass; }
set themeClass(value: string) {
if (this._containerElement) {
if (this._themeClass) {
this._containerElement.classList.remove(this._themeClass);
}
if (value) {
this._containerElement.classList.add(value);
}
}
this._themeClass = value;
}
ngOnDestroy() {
if (this._containerElement && this._containerElement.parentNode) {
this._containerElement.parentNode.removeChild(this._containerElement);
@@ -44,7 +24,7 @@ export class OverlayContainer implements OnDestroy {
}
/**
* This method returns the overlay container element. It will lazily
* This method returns the overlay container element. It will lazily
* create the element the first time it is called to facilitate using
* the container in non-browser environments.
* @returns the container element
@@ -62,10 +42,6 @@ export class OverlayContainer implements OnDestroy {
let container = document.createElement('div');
container.classList.add('cdk-overlay-container');
if (this._themeClass) {
container.classList.add(this._themeClass);
}
document.body.appendChild(container);
this._containerElement = container;
}
-44
View File
@@ -469,44 +469,6 @@ describe('Overlay', () => {
});
});
describe('OverlayContainer theming', () => {
let overlayContainer: OverlayContainer;
let overlayContainerElement: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({ imports: [OverlayContainerThemingTestModule] });
TestBed.compileComponents();
}));
beforeEach(inject([OverlayContainer], (o: OverlayContainer) => {
overlayContainer = o;
overlayContainerElement = overlayContainer.getContainerElement();
}));
afterEach(() => {
overlayContainerElement.parentNode!.removeChild(overlayContainerElement);
});
it('should be able to set a theme on the overlay container', () => {
overlayContainer.themeClass = 'my-theme';
expect(overlayContainerElement.classList).toContain('my-theme');
});
it('should clear any previously-set themes when a new theme is set', () => {
overlayContainer.themeClass = 'initial-theme';
expect(overlayContainerElement.classList).toContain('initial-theme');
overlayContainer.themeClass = 'new-theme';
expect(overlayContainerElement.classList).not.toContain('initial-theme');
expect(overlayContainerElement.classList).toContain('new-theme');
});
it('should not throw when switching from a blank theme', () => {
overlayContainer.themeClass = '';
expect(() => overlayContainer.themeClass = 'new-theme').not.toThrow();
});
});
/** Simple component for testing ComponentPortal. */
@Component({
selector: 'pizza',
@@ -534,12 +496,6 @@ const TEST_COMPONENTS = [PizzaMsg, TestComponentWithTemplatePortals];
})
class OverlayTestModule { }
/** Component for testing the overlay container theming. */
@NgModule({
imports: [OverlayModule, PortalModule],
})
class OverlayContainerThemingTestModule { }
class FakePositionStrategy implements PositionStrategy {
element: HTMLElement;
+2 -2
View File
@@ -109,10 +109,10 @@ export class DemoApp {
if (this.dark) {
this._renderer.addClass(this._element.nativeElement, darkThemeClass);
this._overlayContainer.themeClass = darkThemeClass;
this._overlayContainer.getContainerElement().classList.add(darkThemeClass);
} else {
this._renderer.removeClass(this._element.nativeElement, darkThemeClass);
this._overlayContainer.themeClass = '';
this._overlayContainer.getContainerElement().classList.remove(darkThemeClass);
}
}
}