mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(overlay): allow theming overlay-based components (#2967)
Fixes #2662.
This commit is contained in:
committed by
Kara
parent
8482bbf636
commit
cbd42f0ef4
@@ -44,6 +44,24 @@ Finally, if your app's content **is not** placed inside of a `md-sidenav-contain
|
||||
need to add the `mat-app-background` class to your wrapper element (for example the `body`). This
|
||||
ensures that the proper theme background is applied to your page.
|
||||
|
||||
#### Theming overlay-based components
|
||||
Since certain components (e.g. `dialog`) are inside of a global overlay container, your theme may
|
||||
not be applied to them. In order to define the theme that will be used for overlay components, you
|
||||
have to specify it on the global `OverlayContainer` instance:
|
||||
|
||||
```ts
|
||||
import {OverlayContainer} from '@angular/material';
|
||||
|
||||
@NgModule({
|
||||
// misc config goes here
|
||||
})
|
||||
export class YourAppModule {
|
||||
constructor(overlayContainer: OverlayContainer) {
|
||||
overlayContainer.themeClass = 'your-theme';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Defining a custom theme
|
||||
When you want more customization than a pre-built theme offers, you can create your own theme file.
|
||||
|
||||
|
||||
@@ -9,6 +9,24 @@ import {Injectable, Optional, SkipSelf} from '@angular/core';
|
||||
export class OverlayContainer {
|
||||
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) {
|
||||
this._containerElement.classList.remove(this._themeClass);
|
||||
|
||||
if (value) {
|
||||
this._containerElement.classList.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
this._themeClass = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the overlay container element. It will lazily
|
||||
* create the element the first time it is called to facilitate using
|
||||
@@ -27,6 +45,11 @@ export class OverlayContainer {
|
||||
protected _createContainer(): void {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -272,6 +272,34 @@ 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();
|
||||
}));
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
/** Simple component for testing ComponentPortal. */
|
||||
@Component({template: '<p>Pizza</p>'})
|
||||
@@ -297,6 +325,12 @@ const TEST_COMPONENTS = [PizzaMsg, TestComponentWithTemplatePortals];
|
||||
})
|
||||
class OverlayTestModule { }
|
||||
|
||||
/** Component for testing the overlay container theming. */
|
||||
@NgModule({
|
||||
imports: [OverlayModule, PortalModule],
|
||||
})
|
||||
class OverlayContainerThemingTestModule { }
|
||||
|
||||
class FakePositionStrategy implements PositionStrategy {
|
||||
apply(element: Element): Promise<void> {
|
||||
element.classList.add('fake-positioned');
|
||||
|
||||
Reference in New Issue
Block a user