ng-alertbar
Version:
A configurable alertbar for Angular
387 lines (377 loc) • 12.1 kB
JavaScript
import { DomSanitizer } from '@angular/platform-browser';
import { filter, mapTo, switchMap, take, takeUntil } from 'rxjs/operators';
import { animate, style, transition, trigger } from '@angular/animations';
import { Subject, timer } from 'rxjs';
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, Output, NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const slide = trigger('slide', [
transition(':enter', [style({ transform: 'translateY(-100%)' }), animate('300ms ease-out')]),
transition(':leave', [animate('200ms ease-in', style({ transform: 'translateY(-100%' }))])
]);
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const defaults = {
queueingEnabled: true,
lifeTimeMs: 5000,
showDelayMs: 100,
backgroundColor: 'linear-gradient(to top right, #9ce29c, #c9f9b9)',
borderColor: '#34a40e',
textColor: 'black',
widthMode: 'partial',
closeButtonEnabled: true,
useHtml: false
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NgAlertbarService {
constructor() {
this._trigger = new Subject();
this.trigger$ = this._trigger.asObservable();
this._cancel = new Subject();
this.cancel$ = this._cancel.asObservable();
}
/**
* Triggers an alert with the given message and options
*
* If no options are passed, the alert will use the existing component configuration
*
* The options provided will only apply to the alert that opens from this trigger
*
* @param {?} message The message to display within the alert
* @param {?=} options One off alert options to apply for this alert instance
* @return {?}
*/
triggerAlert(message, options) {
this._trigger.next({ message: message, options: options });
}
/**
* Cancels the currently displayed alert
* @return {?}
*/
cancelAlerts() {
this._cancel.next();
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const ALERT_LEAVE_ANIMATION_DURATION = 200;
class NgAlertbarComponent {
/**
* @param {?} alertBarService
* @param {?} domSanitizer
*/
constructor(alertBarService, domSanitizer) {
this.alertBarService = alertBarService;
this.domSanitizer = domSanitizer;
this.queue = [];
this.queuePop = new Subject();
this.queueing = defaults.queueingEnabled;
this.lifeTime = defaults.lifeTimeMs;
this.showDelay = defaults.showDelayMs;
this.backgroundColor = defaults.backgroundColor;
this.borderColor = defaults.borderColor;
this.textColor = defaults.textColor;
this.widthMode = defaults.widthMode;
this.closeButton = defaults.closeButtonEnabled;
this.html = defaults.useHtml;
this.open = new EventEmitter();
this.close = new EventEmitter();
this.show = false;
this.destroy = new Subject();
}
/**
* @return {?}
*/
get isFullWidth() {
if (this.tempWidthMode) {
return this.tempWidthMode === 'full';
}
return this.widthMode === 'full';
}
/**
* @return {?}
*/
get showCloseButton() {
if (this.tempCloseButton != null) {
return this.tempCloseButton;
}
return this.closeButton;
}
/**
* @return {?}
*/
get useHtml() {
if (this.tempHtml != null) {
return this.tempHtml;
}
return this.html;
}
/**
* @return {?}
*/
get htmlMessage() {
return this.domSanitizer.bypassSecurityTrustHtml(this.message);
}
/**
* The trigger stream after waiting the specified showDelay since the alert was triggered
* @return {?}
*/
get openTriggerPostDelay$() {
return this.alertBarService.trigger$.pipe(switchMap((/**
* @param {?} trigger
* @return {?}
*/
trigger$$1 => {
/** @type {?} */
const options = trigger$$1.options;
/** @type {?} */
const showDelay = (options && options.showDelay) || this.showDelay;
return timer(showDelay).pipe(mapTo(trigger$$1));
})), takeUntil(this.destroy));
}
/**
* The trigger stream after waiting the specified lifetime since the alert opened
* @return {?}
*/
get postAlertLifetime$() {
return this.open.pipe(filter((/**
* @param {?} __0
* @return {?}
*/
({ options }) => this.shouldAlertAutoClose(options))), switchMap((/**
* @param {?} __0
* @return {?}
*/
({ options }) => {
/** @type {?} */
const lifeTime = (options && options.lifeTime) || this.lifeTime;
return timer(lifeTime);
})), takeUntil(this.destroy));
}
/**
* The service cancel trigger
* @return {?}
*/
get cancelTrigger$() {
return this.alertBarService.cancel$.pipe(takeUntil(this.destroy));
}
/**
* Timer representing the delay taken for an alert to animate when exiting
* @return {?}
*/
get alertLeaveTimer() {
return timer(ALERT_LEAVE_ANIMATION_DURATION).pipe(take(1));
}
/**
* @return {?}
*/
ngOnInit() {
this.openTriggerPostDelay$.subscribe((/**
* @param {?} trigger
* @return {?}
*/
trigger$$1 => this.onTrigger(trigger$$1)));
this.queuePop.subscribe((/**
* @param {?} trigger
* @return {?}
*/
trigger$$1 => this.showAlert(trigger$$1)));
this.postAlertLifetime$.subscribe((/**
* @return {?}
*/
() => this.onClose()));
this.cancelTrigger$.subscribe((/**
* @return {?}
*/
() => this.onClose()));
}
/**
* @return {?}
*/
ngOnDestroy() {
this.destroy.next();
}
/**
* @private
* @param {?} trigger
* @return {?}
*/
onTrigger(trigger$$1) {
if (this.queueing && !(trigger$$1.options && trigger$$1.options.bypassQueue) && this.show) {
this.queue.push(trigger$$1);
return;
}
this.showAlert(trigger$$1);
}
/**
* Sets up temp variables and shows the alert
* @private
* @param {?} trigger The trigger to display
* @return {?}
*/
showAlert(trigger$$1) {
this.clearTempOptions(); // Clear previous temporary options
this.assignTempOptions(trigger$$1.options);
this.message = trigger$$1.message;
this.show = true;
this.open.emit(trigger$$1);
}
/**
* Closes any open alert. If there are any alerts waiting in the queue,
* the alert is popped off the queue and emitted for opening
* @return {?}
*/
onClose() {
this.closeAlert();
if (this.queue.length > 0) {
this.alertLeaveTimer.subscribe((/**
* @return {?}
*/
() => {
this.queuePop.next(this.queue.shift());
}));
}
}
/**
* @private
* @return {?}
*/
closeAlert() {
this.show = false;
this.close.emit();
}
/**
* Clears out any temporary config options so that they
* do not persist beyond their single use
* @private
* @return {?}
*/
clearTempOptions() {
this.tempBackgroundColor = null;
this.tempBorderColor = null;
this.tempTextColor = null;
this.tempWidthMode = null;
this.tempCloseButton = null;
this.tempHtml = null;
}
/**
* Assigns the options included in the trigger to the temporary
* config variables so they can apply for the upcoming alert
* @private
* @param {?} options The options passed in the trigger
* @return {?}
*/
assignTempOptions(options) {
if (!options) {
return;
}
this.tempBackgroundColor = options.backgroundColor;
this.tempBorderColor = options.borderColor;
this.tempTextColor = options.textColor;
this.tempWidthMode = options.widthMode;
this.tempCloseButton = options.closeButton;
this.tempHtml = options.html;
}
/**
* @private
* @param {?} options
* @return {?}
*/
shouldAlertAutoClose(options) {
if (options && options.lifeTime != null) {
return options.lifeTime > 0;
}
return this.lifeTime > 0; // Fallback to component setting
}
}
NgAlertbarComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-alertbar',
template: `
<div *ngIf="show" [] class="ng-alert-bar-wrapper">
<div
class="ng-alert-bar"
[class.full-width]="isFullWidth"
[style.background]="tempBackgroundColor || backgroundColor"
[style.border-color]="tempBorderColor || borderColor"
>
<span class="ng-alert-bar-text" [style.color]="tempTextColor || textColor">
<span *ngIf="!useHtml; else htmlMessageContainer">{{ message }}</span>
<ng-template #htmlMessageContainer><span [innerHTML]="htmlMessage"></span></ng-template>
<span *ngIf="showCloseButton" class="ng-alert-close" (click)="onClose()">×</span>
</span>
</div>
</div>
`,
animations: [slide],
styles: [".ng-alert-bar-wrapper{position:absolute;top:0;left:0;width:100%;text-align:center;pointer-events:none}.ng-alert-bar{pointer-events:all}.ng-alert-bar:not(.full-width){display:inline-block}.ng-alert-close{font-size:1.1em;margin-left:.25rem;vertical-align:middle;cursor:pointer}"]
}] }
];
/** @nocollapse */
NgAlertbarComponent.ctorParameters = () => [
{ type: NgAlertbarService },
{ type: DomSanitizer }
];
NgAlertbarComponent.propDecorators = {
queueing: [{ type: Input }],
lifeTime: [{ type: Input }],
showDelay: [{ type: Input }],
backgroundColor: [{ type: Input }],
borderColor: [{ type: Input }],
textColor: [{ type: Input }],
widthMode: [{ type: Input }],
closeButton: [{ type: Input }],
html: [{ type: Input }],
open: [{ type: Output }],
close: [{ type: Output }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NgAlertbarModule {
/**
* @return {?}
*/
static forRoot() {
return {
ngModule: NgAlertbarModule,
providers: [NgAlertbarService]
};
}
}
NgAlertbarModule.decorators = [
{ type: NgModule, args: [{
declarations: [NgAlertbarComponent],
imports: [CommonModule, BrowserAnimationsModule],
exports: [NgAlertbarComponent]
},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { NgAlertbarComponent, NgAlertbarModule, NgAlertbarService, slide as ɵa };
//# sourceMappingURL=ng-alertbar.js.map