import { Observable, Subject } from 'rxjs'; import { animate, keyframes, style, transition, trigger } from '@angular/animations'; import { Component, ComponentFactoryResolver, ElementRef, EventEmitter, HostListener, OnInit, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core'; import { IDialogConfig } from '../interfaces'; interface ComponentType { new(...args: any[]): T; } @Component({ selector: 'cmn-dialog', templateUrl: './dialog.component.html', encapsulation: ViewEncapsulation.None, animations: [ trigger('modalState', [ transition( 'void => active', animate('200ms', keyframes([ style({ opacity: '0', top: '5%', offset: 0 }), style({ opacity: '1', top: '0', offset: 1 }) ])) ), transition( 'active => inactive', animate('200ms', keyframes([ style({ opacity: '1', offset: 0 }), style({ opacity: '0', top: '5%', offset: 1 }) ])) ) ]) ] }) export class DialogComponent implements OnInit { @ViewChild('header') public readonly headerEl: ElementRef; @ViewChild('footer') public readonly footerEl: ElementRef; @ViewChild('okButton') public readonly okButtonEl: ElementRef; @ViewChild('cancelButton') public readonly cancelButtonEl: ElementRef; @ViewChild('backdropButton') public readonly backdropButtonEl: ElementRef; @ViewChild('componentSection', { read: ViewContainerRef }) public readonly componentSection: ViewContainerRef; public open = false; public componentInstance: T; public hasComponent = false; public config: IDialogConfig; public ready = new EventEmitter(); private fromOkButton = false; private afterClosed$: Subject = new Subject(); constructor( private readonly componentFactoryResolver: ComponentFactoryResolver, ) {} public ngOnInit() { this.open = true; this.ready.next(true); console.log(this.okButtonEl); } @HostListener('document:keydown.escape') public keypress() { this.backdropHandler(); } public backdropHandler() { if (this.config.hasBackdrop) { this.dismiss(false); } } public cancelHandler() { this.actionHandler('cancelHandler'); } public okHandler() { this.actionHandler('okHandler', true); } public dismiss(fromOkButton: boolean) { this.open = false; this.fromOkButton = fromOkButton; } public animationDone(event: AnimationEvent) { if ((event as any).fromState === 'active' && (event as any).toState === 'inactive') { this.afterClosed$.next(this.fromOkButton); this.afterClosed$.complete(); } } public afterClosed(): Observable { return this.afterClosed$.asObservable(); } public _setComponent(componentOrTemplateRef: ComponentType | TemplateRef) { if (componentOrTemplateRef instanceof TemplateRef) { this.componentSection.createEmbeddedView(componentOrTemplateRef); } else { const factory = this.componentFactoryResolver.resolveComponentFactory(componentOrTemplateRef); const componentRef = this.componentSection.createComponent(factory); this.componentInstance = componentRef.instance as T; (this.componentInstance as any).modalRef = this; } this.hasComponent = true; } private actionHandler(action: 'okHandler' | 'cancelHandler', isDismiss: boolean = false) { if (this.config[action]) { this.config[action](); } else { this.dismiss(isDismiss); } } }