mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
committed by
vivian-hu
parent
ab44d50f5f
commit
3de38511e6
@@ -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`.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user