license 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 , InjectionToken , Inject , OnDestroy , } from '@angular/core' ; import { Location } from '@angular/common' ; import { of as observableOf } from 'rxjs' ; import { MAT_BOTTOM_SHEET_DATA , MatBottomSheetConfig } from './bottom-sheet-config' ; import { MatBottomSheetContainer } from './bottom-sheet-container' ; 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.
 */ @ Injectable ( { providedIn : MatBottomSheetModule } ) export class MatBottomSheet implements OnDestroy { private _bottomSheetRefAtThisLevel : MatBottomSheetRef < any > | null = null ; /** Reference to the currently opened bottom sheet. */ get _openedBottomSheetRef ( ) : MatBottomSheetRef < any > | null { const parent = this . _parentBottomSheet ; return parent ? parent . _openedBottomSheetRef : this . _bottomSheetRefAtThisLevel ; } set _openedBottomSheetRef ( value ) { if ( this . _parentBottomSheet ) { this . _parentBottomSheet . _openedBottomSheetRef = value ; } else { this . _bottomSheetRefAtThisLevel = value ; } } constructor ( private _overlay , private _injector , @ Optional ( ) @ SkipSelf ( ) private _parentBottomSheet , @ Optional ( ) private _location ? , @ Optional ( ) @ Inject ( MAT_BOTTOM_SHEET_DEFAULT_OPTIONS ) private _defaultOptions ? ) { } open < T , D = any , R = any > ( component , config ? ) ; open < T , D = any , R = any > ( template , config ? ) ; open < T , D = any , R = any > ( componentOrTemplateRef , 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 ) ; if ( componentOrTemplateRef instanceof TemplateRef ) { container . attachTemplatePortal ( new TemplatePortal < T > ( componentOrTemplateRef , null ! , { $implicit : _config . data , bottomSheetRef : ref } as any ) ) ; } else { const portal = new ComponentPortal ( componentOrTemplateRef , undefined , this . _createInjector ( _config , ref ) ) ; const contentRef = container . attachComponentPortal ( portal ) ; ref . instance = contentRef . instance ; } ref . afterDismissed ( ) . subscribe ( ( ) => { if ( this . _openedBottomSheetRef == ref ) { this . _openedBottomSheetRef = null ; } } ) ; if ( this . _openedBottomSheetRef ) { this . _openedBottomSheetRef . afterDismissed ( ) . subscribe ( ( ) => ref . containerInstance . enter ( ) ) ; this . _openedBottomSheetRef . dismiss ( ) ; } else { ref . containerInstance . enter ( ) ; } this . _openedBottomSheetRef = ref ; return ref ; } /**
     * Dismisses the currently-visible bottom sheet.
     */ dismiss ( ) { if ( this . _openedBottomSheetRef ) { this . _openedBottomSheetRef . dismiss ( ) ; } } ngOnDestroy ( ) { if ( this . _bottomSheetRefAtThisLevel ) { this . _bottomSheetRefAtThisLevel . dismiss ( ) ; } } /**
     * Attaches the bottom sheet container component to the overlay.
     */ private _attachContainer ( overlayRef , config ) { const userInjector = config && config . viewContainerRef && config . viewContainerRef . injector ; const injector = new PortalInjector ( userInjector || this . _injector , new WeakMap ( [ [ MatBottomSheetConfig , config ] ] ) ) ; const containerPortal = new ComponentPortal ( MatBottomSheetContainer , config . viewContainerRef , injector ) ; const containerRef = overlayRef . attach ( containerPortal ) ; return containerRef . instance ; } param config private _createOverlay ( config ) { const overlayConfig = new OverlayConfig ( { direction : config . direction , hasBackdrop : config . hasBackdrop , disposeOnNavigation : config . closeOnNavigation , maxWidth : '100%' , scrollStrategy : this . _overlay . scrollStrategies . block ( ) , positionStrategy : this . _overlay . position ( ) . global ( ) . centerHorizontally ( ) . bottom ( '0' ) } ) ; if ( config . backdropClass ) { overlayConfig . backdropClass = config . backdropClass ; } return this . _overlay . create ( overlayConfig ) ; } param config param bottomSheetRef private _createInjector < T > ( config , bottomSheetRef ) { const userInjector = config && config . viewContainerRef && config . viewContainerRef . injector ; const injectionTokens = new WeakMap < any , any > ( [ [ MatBottomSheetRef , bottomSheetRef ] , [ MAT_BOTTOM_SHEET_DATA , config . data ] ] ) ; if ( config . direction && ( ! userInjector || ! userInjector . get < Directionality | null > ( Directionality , null ) ) ) { injectionTokens . set ( Directionality , { value : config . direction , change : observableOf ( ) } ) ; } return new PortalInjector ( userInjector || this . _injector , injectionTokens ) ; } } param defaults param config returns function _applyConfigDefaults ( defaults , config ? ) { return { ... defaults , ... config } ; }