import { Injectable , ComponentRef , Renderer2 , RendererFactory2 } from '@angular/core' ; import { Subscription } from 'rxjs' ; import { InjectionService } from '../../services/injection/injection.service' ; import { InjectionRegistryService } from '../../services/injection-registry/injection-registry.service' ; import { DrawerComponent } from './drawer.component' ; import { OverlayService } from '../overlay/overlay.service' ; import { DrawerDirection } from './drawer-direction.enum' ; import { DrawerOptions } from './drawer-options.interface' ; @ Injectable ( { providedIn : 'root' } ) export class DrawerService extends InjectionRegistryService < DrawerComponent > { type : any = DrawerComponent ; readonly defaults : DrawerOptions = { inputs : { direction : DrawerDirection . Left } } ; readonly renderer : Renderer2 ; private zIndex = 995 ; private size = 80 ; private parentListenerFunc : ( ) => void ; constructor ( readonly injectionService , private readonly overlayService , private readonly rendererFactory ) { super ( injectionService ) ; this . renderer = this . rendererFactory . createRenderer ( null , null ) ; } create ( options ) { const component = super . create ( options ) ; this . createSubscriptions ( component , options . isRoot , options . parentContainer ) ; return component ; } destroy ( component ) { if ( component && component . instance ) { component . instance . size = 0 ; } setTimeout ( ( ) => { this . zIndex = this . zIndex - 2 ; this . size = this . size + 10 ; this . overlayService . removeTriggerComponent ( component ) ; super . destroy ( component ) ; } , 10 ) ; } assignDefaults ( options ) { options = super . assignDefaults ( options ) ; if ( ! options . inputs . zIndex ) { this . zIndex = this . overlayService . instance ? this . overlayService . instance . zIndex + 3 : this . zIndex + 2 ; options . inputs . zIndex = this . zIndex ; } this . size = this . size - 10 ; if ( ! options . inputs . size ) { options . inputs . size = this . size ; } return options ; } createSubscriptions ( component , isRoot = true , parentContainer ? ) { if ( isRoot ) { this . overlayService . show ( { triggerComponent : component , zIndex : this . zIndex } ) ; } let closeSub ; let overlaySub ; const kill = ( c ) => { if ( component !== c ) { return ; } closeSub . unsubscribe ( ) ; if ( overlaySub ) { overlaySub . unsubscribe ( ) ; } if ( this . parentListenerFunc && this . components . get ( this . type ) . length === 1 ) { this . parentListenerFunc ( ) ; } this . destroy ( component ) ; } ; closeSub = component . instance . close . subscribe ( kill . bind ( this , component ) ) ; if ( component . instance . closeOnOutsideClick ) { if ( isRoot ) { overlaySub = this . overlayService . click . subscribe ( kill ) ; } else { const components = this . components . get ( this . type ) ; this . parentListenerFunc = this . renderer . listen ( parentContainer , 'click' , evt => { if ( evt . target === parentContainer ) { kill ( components [ components . length - 1 ] ) ; } } ) ; } } } }