novo-elements
Version:
165 lines (157 loc) • 8.9 kB
JavaScript
import { Subject } from 'rxjs';
import { filter, take } from 'rxjs/operators';
import { trigger, state, style, transition, animate } from '@angular/animations';
import * as i2 from '@angular/cdk/portal';
import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
import * as i0 from '@angular/core';
import { EventEmitter, Output, Component, Injector, Injectable, NgModule } from '@angular/core';
import * as i1 from '@angular/cdk/overlay';
import { OverlayModule } from '@angular/cdk/overlay';
class NovoAsideRef {
constructor(component, params, overlayRef) {
this.component = component;
this.params = params;
this.overlayRef = overlayRef;
this._beforeClose = new Subject();
this._afterClosed = new Subject();
this.isClosed = false;
}
// Gets a promise that is resolved when the dialog is closed.
get onClosed() {
return this._afterClosed.toPromise();
}
afterClosed() {
return this._afterClosed.asObservable();
}
beforeClose() {
return this._beforeClose.asObservable();
}
close(result) {
// Listen for animation 'start' events
this.componentInstance.animationStateChanged
.pipe(filter((event) => event.phaseName === 'start'), take(1))
.subscribe(() => {
this._beforeClose.next(result);
this._beforeClose.complete();
this.overlayRef.detachBackdrop();
});
// Listen for animation 'done' events
this.componentInstance.animationStateChanged
.pipe(filter((event) => event.phaseName === 'done' && event.toState === 'leave'), take(1))
.subscribe(() => {
this.isClosed = true;
this.overlayRef.dispose();
this._afterClosed.next(result);
this._afterClosed.complete();
// Make sure to also clear the reference to the
// component instance to avoid memory leaks
this.componentInstance = null;
});
// Start exit animation
this.componentInstance.startExitAnimation();
}
}
const slideInOut = trigger('slideInOut', [
state('void', style({ transform: 'translateX(100%)' })),
state('enter', style({ transform: 'none' })),
state('leave', style({ transform: 'translateX(100%)' })),
transition('* => *', animate('800ms cubic-bezier(0.2, 1, 0.3, 1)')),
]);
class AsideComponent {
constructor(injector, asideRef) {
this.injector = injector;
this.asideRef = asideRef;
this.animationStateChanged = new EventEmitter();
this.animationState = 'enter';
this.component = new ComponentPortal(asideRef.component, null, injector);
}
onAnimationStart(event) {
this.animationStateChanged.emit(event);
}
onAnimationDone(event) {
this.animationStateChanged.emit(event);
}
startExitAnimation() {
this.animationState = 'leave';
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AsideComponent, deps: [{ token: i0.Injector }, { token: NovoAsideRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: AsideComponent, isStandalone: false, selector: "novo-aside", outputs: { animationStateChanged: "animationStateChanged" }, ngImport: i0, template: "<div class=\"aside-panel\" [@slideInOut]=\"animationState\" (@slideInOut.start)=\"onAnimationStart($event)\"\n (@slideInOut.done)=\"onAnimationDone($event)\">\n <ng-template [cdkPortalOutlet]=\"component\"></ng-template>\n</div>", styles: [":host .aside-panel{background-color:var(--background-bright, #ffffff);height:100vh;width:50%;min-width:min-content;max-width:540px;position:absolute;top:0;right:0;padding:0;display:flex;justify-content:stretch;align-items:stretch}\n"], dependencies: [{ kind: "directive", type: i2.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], animations: [slideInOut] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AsideComponent, decorators: [{
type: Component,
args: [{ selector: 'novo-aside', animations: [slideInOut], standalone: false, template: "<div class=\"aside-panel\" [@slideInOut]=\"animationState\" (@slideInOut.start)=\"onAnimationStart($event)\"\n (@slideInOut.done)=\"onAnimationDone($event)\">\n <ng-template [cdkPortalOutlet]=\"component\"></ng-template>\n</div>", styles: [":host .aside-panel{background-color:var(--background-bright, #ffffff);height:100vh;width:50%;min-width:min-content;max-width:540px;position:absolute;top:0;right:0;padding:0;display:flex;justify-content:stretch;align-items:stretch}\n"] }]
}], ctorParameters: () => [{ type: i0.Injector }, { type: NovoAsideRef }], propDecorators: { animationStateChanged: [{
type: Output
}] } });
const DEFAULT_CONFIG = {
hasBackdrop: true,
backdropClass: 'aside-overlay-backdrop',
panelClass: 'aside-overlay-panel',
};
class NovoAsideService {
constructor(injector, overlay) {
this.injector = injector;
this.overlay = overlay;
}
open(component, params = {}, config = {}) {
// Override default configuration
const asideConfig = this.getOverlayConfig({ ...DEFAULT_CONFIG, ...config });
// Returns an OverlayRef which is a PortalHost
const overlayRef = this.createOverlay(asideConfig);
// Instantiate remote control
const asideRef = new NovoAsideRef(component, params, overlayRef);
const overlayComponent = this.attachAsideContainer(AsideComponent, overlayRef, asideConfig, asideRef);
// Pass the instance of the overlay component to the remote control
asideRef.componentInstance = overlayComponent;
overlayRef.backdropClick().subscribe(() => asideRef.close());
return asideRef;
}
createOverlay(config) {
return this.overlay.create(config);
}
attachAsideContainer(component, overlayRef, config, asideRef) {
const injector = this.createInjector(config, asideRef);
const containerPortal = new ComponentPortal(component, null, injector);
const containerRef = overlayRef.attach(containerPortal);
return containerRef.instance;
}
createInjector(config, asideRef) {
return Injector.create({
parent: this.injector,
providers: [{ provide: NovoAsideRef, useValue: asideRef }],
});
}
getOverlayConfig(config) {
const scrollStrategy = config.hasBackdrop ? this.overlay.scrollStrategies.block() : this.overlay.scrollStrategies.noop();
return {
scrollStrategy,
hasBackdrop: config.hasBackdrop,
backdropClass: config.backdropClass,
panelClass: config.panelClass,
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoAsideService, deps: [{ token: i0.Injector }, { token: i1.Overlay }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoAsideService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoAsideService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i0.Injector }, { type: i1.Overlay }] });
class NovoAsideModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoAsideModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: NovoAsideModule, declarations: [AsideComponent], imports: [OverlayModule, PortalModule] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoAsideModule, providers: [NovoAsideService], imports: [OverlayModule, PortalModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoAsideModule, decorators: [{
type: NgModule,
args: [{
imports: [OverlayModule, PortalModule],
declarations: [AsideComponent],
providers: [NovoAsideService],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { AsideComponent, NovoAsideModule, NovoAsideRef, NovoAsideService, slideInOut };
//# sourceMappingURL=novo-elements-elements-aside.mjs.map