feat(bottom-sheet): add injection token for default options (#13172)

Introduces the `MAT_BOTTOM_SHEET_DEFAULT_OPTIONS` token which can be used to set the default options for `MatBottomSheet`.

Fixes #13149.
This commit is contained in:
Kristiyan Kostadinov
2018-10-02 22:24:15 +02:00
committed by vivian-hu
parent ab44d50f5f
commit 3de38511e6
3 changed files with 113 additions and 6 deletions
+13
View File
@@ -81,6 +81,19 @@ inside your `NgModule`.
export class AppModule {}
```
### Specifying global configuration defaults
Default bottom sheet options can be specified by providing an instance of `MatBottomSheetConfig`
for `MAT_BOTTOM_SHEET_DEFAULT_OPTIONS` in your application's root module.
```ts
@NgModule({
providers: [
{provide: MAT_BOTTOM_SHEET_DEFAULT_OPTIONS, useValue: {hasBackdrop: false}}
]
})
```
### Accessibility
By default, the bottom sheet has `role="dialog"` on the root element and can be labelled using the
`ariaLabel` property on the `MatBottomSheetConfig`.
+77 -1
View File
@@ -25,7 +25,7 @@ import {
import {Location} from '@angular/common';
import {SpyLocation} from '@angular/common/testing';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MatBottomSheet} from './bottom-sheet';
import {MatBottomSheet, MAT_BOTTOM_SHEET_DEFAULT_OPTIONS} from './bottom-sheet';
import {MAT_BOTTOM_SHEET_DATA, MatBottomSheetConfig} from './bottom-sheet-config';
import {MatBottomSheetModule} from './bottom-sheet-module';
import {MatBottomSheetRef} from './bottom-sheet-ref';
@@ -616,6 +616,82 @@ describe('MatBottomSheet with parent MatBottomSheet', () => {
}));
});
describe('MatBottomSheet with default options', () => {
let bottomSheet: MatBottomSheet;
let overlayContainer: OverlayContainer;
let overlayContainerElement: HTMLElement;
let testViewContainerRef: ViewContainerRef;
let viewContainerFixture: ComponentFixture<ComponentWithChildViewContainer>;
beforeEach(fakeAsync(() => {
const defaultConfig: MatBottomSheetConfig = {
hasBackdrop: false,
disableClose: true,
autoFocus: false
};
TestBed.configureTestingModule({
imports: [MatBottomSheetModule, BottomSheetTestModule],
providers: [
{provide: MAT_BOTTOM_SHEET_DEFAULT_OPTIONS, useValue: defaultConfig},
],
});
TestBed.compileComponents();
}));
beforeEach(inject([MatBottomSheet, OverlayContainer],
(b: MatBottomSheet, oc: OverlayContainer) => {
bottomSheet = b;
overlayContainer = oc;
overlayContainerElement = oc.getContainerElement();
}));
afterEach(() => {
overlayContainer.ngOnDestroy();
});
beforeEach(() => {
viewContainerFixture = TestBed.createComponent(ComponentWithChildViewContainer);
viewContainerFixture.detectChanges();
testViewContainerRef = viewContainerFixture.componentInstance.childViewContainer;
});
it('should use the provided defaults', () => {
bottomSheet.open(PizzaMsg, {viewContainerRef: testViewContainerRef});
viewContainerFixture.detectChanges();
expect(overlayContainerElement.querySelector('.cdk-overlay-backdrop')).toBeFalsy();
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
expect(overlayContainerElement.querySelector('mat-bottom-sheet-container')).toBeTruthy();
expect(document.activeElement.tagName).not.toBe('INPUT');
});
it('should be overridable by open() options', fakeAsync(() => {
bottomSheet.open(PizzaMsg, {
hasBackdrop: true,
disableClose: false,
viewContainerRef: testViewContainerRef
});
viewContainerFixture.detectChanges();
expect(overlayContainerElement.querySelector('.cdk-overlay-backdrop')).toBeTruthy();
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
viewContainerFixture.detectChanges();
flush();
expect(overlayContainerElement.querySelector('mat-bottom-sheet-container')).toBeFalsy();
}));
});
@Directive({selector: 'dir-with-view-container'})
class DirectiveWithViewContainer {
+23 -5
View File
@@ -9,7 +9,16 @@
import {Directionality} from '@angular/cdk/bidi';
import {Overlay, OverlayConfig, OverlayRef} from '@angular/cdk/overlay';
import {ComponentPortal, ComponentType, PortalInjector, TemplatePortal} from '@angular/cdk/portal';
import {ComponentRef, Injectable, Injector, Optional, SkipSelf, TemplateRef} from '@angular/core';
import {
ComponentRef,
Injectable,
Injector,
Optional,
SkipSelf,
TemplateRef,
InjectionToken,
Inject,
} from '@angular/core';
import {Location} from '@angular/common';
import {of as observableOf} from 'rxjs';
import {MAT_BOTTOM_SHEET_DATA, MatBottomSheetConfig} from './bottom-sheet-config';
@@ -18,6 +27,10 @@ import {MatBottomSheetModule} from './bottom-sheet-module';
import {MatBottomSheetRef} from './bottom-sheet-ref';
/** Injection token that can be used to specify default bottom sheet options. */
export const MAT_BOTTOM_SHEET_DEFAULT_OPTIONS =
new InjectionToken<MatBottomSheetConfig>('mat-bottom-sheet-default-options');
/**
* Service to trigger Material Design bottom sheets.
*/
@@ -43,7 +56,9 @@ export class MatBottomSheet {
private _overlay: Overlay,
private _injector: Injector,
@Optional() @SkipSelf() private _parentBottomSheet: MatBottomSheet,
@Optional() private _location?: Location) {}
@Optional() private _location?: Location,
@Optional() @Inject(MAT_BOTTOM_SHEET_DEFAULT_OPTIONS)
private _defaultOptions?: MatBottomSheetConfig) {}
open<T, D = any, R = any>(component: ComponentType<T>,
config?: MatBottomSheetConfig<D>): MatBottomSheetRef<T, R>;
@@ -53,7 +68,8 @@ export class MatBottomSheet {
open<T, D = any, R = any>(componentOrTemplateRef: ComponentType<T> | TemplateRef<T>,
config?: MatBottomSheetConfig<D>): MatBottomSheetRef<T, R> {
const _config = _applyConfigDefaults(config);
const _config =
_applyConfigDefaults(this._defaultOptions || new MatBottomSheetConfig(), config);
const overlayRef = this._createOverlay(_config);
const container = this._attachContainer(overlayRef, _config);
const ref = new MatBottomSheetRef<T, R>(container, overlayRef, this._location);
@@ -171,9 +187,11 @@ export class MatBottomSheet {
/**
* Applies default options to the bottom sheet config.
* @param defaults Object containing the default values to which to fall back.
* @param config The configuration to which the defaults will be applied.
* @returns The new configuration object with defaults applied.
*/
function _applyConfigDefaults(config?: MatBottomSheetConfig): MatBottomSheetConfig {
return {...new MatBottomSheetConfig(), ...config};
function _applyConfigDefaults(defaults: MatBottomSheetConfig,
config?: MatBottomSheetConfig): MatBottomSheetConfig {
return {...defaults, ...config};
}