UNPKG

@christophhu/ngx-notifications

Version:

An Angular notifications library to create beautiful notifications with animations.

223 lines (212 loc) 23.9 kB
import * as i0 from '@angular/core'; import { InjectionToken, provideAppInitializer, inject, makeEnvironmentProviders, Pipe, Injectable, EventEmitter, Output, Inject, Component } from '@angular/core'; import { Subject, Observable, takeUntil } from 'rxjs'; import * as i2 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i1 from '@angular/platform-browser'; import { trigger, state, transition, style, animate } from '@angular/animations'; /** * Provide an Injection Token for global settings. */ const NGX_NOTIFICATIONS_OPTIONS_TOKEN = new InjectionToken('ngx-notifications-options-token', { factory: () => ({ type: 'info', position: 'top-right', header: '', message: '', autoclose: true, timeout: 15000, max: 5 }) }); const NGX_NOTIFICATIONS_INITIALIZER_PROVIDER = [ provideAppInitializer(() => NotificationsInitializer(inject(NGX_NOTIFICATIONS_OPTIONS_TOKEN))) ]; function NotificationsInitializer(options) { // const notificationService = inject(NotificationService) // notificationService.setDefault({ type: 'info', position: 'top-right', header: '', message: '', autoclose: true, timeout: 15000, max: 5 }) console.log('NotificationsInitializer', options); return new Promise((resolve) => { resolve(); }); } function provideNotifications(options) { return makeEnvironmentProviders([ { provide: NGX_NOTIFICATIONS_OPTIONS_TOKEN, useValue: options }, NGX_NOTIFICATIONS_INITIALIZER_PROVIDER ]); } class SaveHtmlPipe { sanitized; constructor(sanitized) { this.sanitized = sanitized; } transform(value) { return this.sanitized.bypassSecurityTrustHtml(value); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: SaveHtmlPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.8", ngImport: i0, type: SaveHtmlPipe, isStandalone: true, name: "saveHtml" }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: SaveHtmlPipe, decorators: [{ type: Pipe, args: [{ name: 'saveHtml' }] }], ctorParameters: () => [{ type: i1.DomSanitizer }] }); const fadeInRight = trigger('fadeInRight', [ state('void', style({ opacity: 0, transform: 'translate3d(100%, 0, 0)' })), state('*', style({ opacity: 1, transform: 'translate3d(0, 0, 0)' })), transition('void => false', []), transition('void => *', animate('200ms 200ms cubic-bezier(0.0, 0.0, 0.2, 1)')) ]); const fadeOutRight = trigger('fadeOutRight', [ state('*', style({ opacity: 1, transform: 'translate3d(0, 0, 0)' })), state('void', style({ opacity: 0, transform: 'translate3d(100%, 0, 0)' })), transition('false => void', []), transition('* => void', animate('200ms 50ms cubic-bezier(0.0, 0.0, 0.2, 1)')) ]); class NotificationsService { _notificationsService = new Subject(); get() { return this._notificationsService.asObservable(); } open(notification) { return new Observable(observer => { const note = Object.assign({}, notification, { response: (response) => { observer.next(response); observer.complete(); } }); this.add(note); }); } add(data) { this._notificationsService.next({ action: 'add', data: data }); } remove(id) { this._notificationsService.next({ action: 'remove', id }); } clear() { this._notificationsService.next({ action: 'clear' }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: NotificationsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: NotificationsService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: NotificationsService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class NotificationComponent { _notificationsService; options; position; onAdd = new EventEmitter(); onRemove = new EventEmitter(); onClear = new EventEmitter(); notifications = []; _notifications_options; // private default_values: Partial<Notification> destroy$ = new Subject(); constructor(_notificationsService, options) { this._notificationsService = _notificationsService; this.options = options; this._notifications_options = options; this.position = this._notifications_options.position; this._notificationsService.get() .pipe(takeUntil(this.destroy$)) .subscribe((notification) => { if (!notification) return; switch (notification.action) { case 'add': this.add(notification.data); break; case 'remove': this.remove(notification.id); break; case 'clear': this.clear(); break; } }); } ngOnDestroy() { this.destroy$.next(true); this.destroy$.unsubscribe(); } add(notification) { notification = Object.assign({}, this._notifications_options, notification); let timeout; const id = this.uuid(); if (this._notifications_options.max && this.notifications.length === this._notifications_options.max) { this.remove(this.notifications[0].id); } if (notification.autoClose && notification.timeout) { timeout = setTimeout(() => { this.remove(id); }, notification.timeout || this._notifications_options.timeout); } notification = Object.assign({ id: id, timeoutObj: timeout }, notification); if (notification.onAdd) { notification.onAdd(notification); } if (this.onAdd) { this.onAdd.emit(notification); } this.notifications.push(notification); } remove(id) { const notification = this.notifications.find(obj => obj.id === id); if (notification) { if (notification.onRemove) { notification.onRemove(notification); } if (this.onRemove) { this.onRemove.emit(notification); } if (notification.timeoutObj) { clearTimeout(notification.timeoutObj); } } this.notifications = this.notifications.filter(obj => obj.id !== id); } clear() { if (this.notifications.length === 0) return; this.notifications = []; if (this.onClear) { this.onClear.emit(true); } } uuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: NotificationComponent, deps: [{ token: NotificationsService }, { token: NGX_NOTIFICATIONS_OPTIONS_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.8", type: NotificationComponent, isStandalone: true, selector: "notification", outputs: { onAdd: "onAdd", onRemove: "onRemove", onClear: "onClear" }, providers: [ SaveHtmlPipe ], ngImport: i0, template: "<div class=\"fixed flex flex-col z-110 w-full md:w-128\" [ngClass]=\"position\">\r\n <div *ngFor=\"let notification of notifications\" class=\"flex w-full md:w-128\" @fadeInRight @fadeOutRight>\r\n <ng-container *ngIf=\"notification.type === 'error'\">\r\n <div class=\"relative flex w-full m-2 items-center justify-start bg-tertiary border border-borderline text-darker text-base rounded-lg shadow-lg\">\r\n <div class=\"h-full w-20 p-2 flex flex-none items-center justify-center bg-red-400 w-12 h-12 text-white rounded-l-md\">\r\n <div class=\"h-8 w-8 stroke-2 fill-none\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentFill\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0\" /><path d=\"M12 8v4\" /><path d=\"M12 16h.01\" /></svg>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col flex-1 justify-center p-4\">\r\n <p class=\"text-lg text-darker font-semibold pb-1\">{{ notification.header }}</p>\r\n <p class=\"text-sm text-dark font-normal line-clamp\">{{ notification.message }}</p>\r\n </div>\r\n <div class=\"flex flex-col flex-none justify-around h-full w-24 border-l border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(true); remove(notification.id)\">OK</div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"notification.type === 'request'\">\r\n <div class=\"relative flex w-full m-2 items-center justify-start bg-tertiary border border-borderline text-darker text-base rounded-lg shadow-lg\">\r\n <div class=\"h-full w-20 p-2 flex flex-none items-center justify-center bg-blue-400 w-12 h-12 text-white rounded-l-md\">\r\n <div class=\"h-8 w-8 stroke-2 fill-none\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentFill\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z\" /></svg>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col flex-1 justify-center p-4\">\r\n <p class=\"text-lg text-darker font-semibold pb-1\">{{ notification.header }}</p>\r\n <p class=\"text-sm text-dark font-normal line-clamp\">{{ notification.message }}</p>\r\n </div>\r\n <div class=\"flex flex-col flex-none justify-around h-full w-24 border-l border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(true); remove(notification.id)\">Ja</div>\r\n <hr class=\"border-t border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(false); remove(notification.id)\">Nein</div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"notification.type === 'success'\">\r\n <div class=\"relative flex w-full m-2 items-center justify-start bg-tertiary border border-borderline text-darker text-base rounded-lg shadow-lg\">\r\n <div class=\"h-full w-20 p-2 flex flex-none items-center justify-center bg-green-400 w-12 h-12 text-white rounded-l-md\">\r\n <div class=\"h-8 w-8 stroke-2 fill-none\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentFill\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\" /><path d=\"M9 12l2 2l4 -4\" /></svg>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col flex-1 justify-center p-4\">\r\n <p class=\"text-lg text-darker font-semibold pb-1\">{{ notification.header }}</p>\r\n <p class=\"text-sm text-dark font-normal line-clamp\">{{ notification.message }}</p>\r\n </div>\r\n <div class=\"flex flex-col flex-none justify-around h-full w-24 border-l border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(true); remove(notification.id)\">OK</div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"notification.type === 'warning'\">\r\n <div class=\"relative flex w-full m-2 items-center justify-start bg-tertiary border border-borderline text-darker text-base rounded-lg shadow-lg\">\r\n <div class=\"h-full w-20 p-2 flex flex-none items-center justify-center bg-yellow-400 w-12 h-12 text-white rounded-l-md\">\r\n <div class=\"h-8 w-8 stroke-2 fill-none\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentFill\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z\" /></svg>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col flex-1 justify-center p-4\">\r\n <p class=\"text-lg text-darker font-semibold pb-1\">{{ notification.header }}</p>\r\n <p class=\"text-sm text-dark font-normal line-clamp\">{{ notification.message }}</p>\r\n </div>\r\n <div class=\"flex flex-col flex-none justify-around h-full w-24 border-l border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(true); remove(notification.id)\">Ja</div>\r\n <hr class=\"border-t border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(false); remove(notification.id)\">Nein</div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>", styles: [".bottom-left{left:0;bottom:0;align-items:flex-start}.bottom-center{bottom:0;left:50%;transform:translate(-50%);align-items:center}.bottom-right{right:0;bottom:0;align-items:flex-end}.top-left{top:0;left:0;align-items:flex-start}.top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.top-right{top:0;right:0;align-items:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], animations: [fadeInRight, fadeOutRight] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: NotificationComponent, decorators: [{ type: Component, args: [{ selector: 'notification', imports: [ CommonModule ], providers: [ SaveHtmlPipe ], animations: [fadeInRight, fadeOutRight], template: "<div class=\"fixed flex flex-col z-110 w-full md:w-128\" [ngClass]=\"position\">\r\n <div *ngFor=\"let notification of notifications\" class=\"flex w-full md:w-128\" @fadeInRight @fadeOutRight>\r\n <ng-container *ngIf=\"notification.type === 'error'\">\r\n <div class=\"relative flex w-full m-2 items-center justify-start bg-tertiary border border-borderline text-darker text-base rounded-lg shadow-lg\">\r\n <div class=\"h-full w-20 p-2 flex flex-none items-center justify-center bg-red-400 w-12 h-12 text-white rounded-l-md\">\r\n <div class=\"h-8 w-8 stroke-2 fill-none\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentFill\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0\" /><path d=\"M12 8v4\" /><path d=\"M12 16h.01\" /></svg>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col flex-1 justify-center p-4\">\r\n <p class=\"text-lg text-darker font-semibold pb-1\">{{ notification.header }}</p>\r\n <p class=\"text-sm text-dark font-normal line-clamp\">{{ notification.message }}</p>\r\n </div>\r\n <div class=\"flex flex-col flex-none justify-around h-full w-24 border-l border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(true); remove(notification.id)\">OK</div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"notification.type === 'request'\">\r\n <div class=\"relative flex w-full m-2 items-center justify-start bg-tertiary border border-borderline text-darker text-base rounded-lg shadow-lg\">\r\n <div class=\"h-full w-20 p-2 flex flex-none items-center justify-center bg-blue-400 w-12 h-12 text-white rounded-l-md\">\r\n <div class=\"h-8 w-8 stroke-2 fill-none\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentFill\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z\" /></svg>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col flex-1 justify-center p-4\">\r\n <p class=\"text-lg text-darker font-semibold pb-1\">{{ notification.header }}</p>\r\n <p class=\"text-sm text-dark font-normal line-clamp\">{{ notification.message }}</p>\r\n </div>\r\n <div class=\"flex flex-col flex-none justify-around h-full w-24 border-l border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(true); remove(notification.id)\">Ja</div>\r\n <hr class=\"border-t border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(false); remove(notification.id)\">Nein</div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"notification.type === 'success'\">\r\n <div class=\"relative flex w-full m-2 items-center justify-start bg-tertiary border border-borderline text-darker text-base rounded-lg shadow-lg\">\r\n <div class=\"h-full w-20 p-2 flex flex-none items-center justify-center bg-green-400 w-12 h-12 text-white rounded-l-md\">\r\n <div class=\"h-8 w-8 stroke-2 fill-none\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentFill\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\" /><path d=\"M9 12l2 2l4 -4\" /></svg>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col flex-1 justify-center p-4\">\r\n <p class=\"text-lg text-darker font-semibold pb-1\">{{ notification.header }}</p>\r\n <p class=\"text-sm text-dark font-normal line-clamp\">{{ notification.message }}</p>\r\n </div>\r\n <div class=\"flex flex-col flex-none justify-around h-full w-24 border-l border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(true); remove(notification.id)\">OK</div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"notification.type === 'warning'\">\r\n <div class=\"relative flex w-full m-2 items-center justify-start bg-tertiary border border-borderline text-darker text-base rounded-lg shadow-lg\">\r\n <div class=\"h-full w-20 p-2 flex flex-none items-center justify-center bg-yellow-400 w-12 h-12 text-white rounded-l-md\">\r\n <div class=\"h-8 w-8 stroke-2 fill-none\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentFill\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z\" /></svg>\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col flex-1 justify-center p-4\">\r\n <p class=\"text-lg text-darker font-semibold pb-1\">{{ notification.header }}</p>\r\n <p class=\"text-sm text-dark font-normal line-clamp\">{{ notification.message }}</p>\r\n </div>\r\n <div class=\"flex flex-col flex-none justify-around h-full w-24 border-l border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(true); remove(notification.id)\">Ja</div>\r\n <hr class=\"border-t border-borderline\">\r\n <div class=\"grid h-full place-items-center text-center cursor-pointer\" (click)=\"notification.response(false); remove(notification.id)\">Nein</div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>", styles: [".bottom-left{left:0;bottom:0;align-items:flex-start}.bottom-center{bottom:0;left:50%;transform:translate(-50%);align-items:center}.bottom-right{right:0;bottom:0;align-items:flex-end}.top-left{top:0;left:0;align-items:flex-start}.top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.top-right{top:0;right:0;align-items:flex-end}\n"] }] }], ctorParameters: () => [{ type: NotificationsService }, { type: undefined, decorators: [{ type: Inject, args: [NGX_NOTIFICATIONS_OPTIONS_TOKEN] }] }], propDecorators: { onAdd: [{ type: Output }], onRemove: [{ type: Output }], onClear: [{ type: Output }] } }); /* * Public API Surface of ngx-notifications */ /** * Generated bundle index. Do not edit. */ export { NotificationComponent, NotificationsService, provideNotifications }; //# sourceMappingURL=christophhu-ngx-notifications.mjs.map