ngx-toastr-notifier
Version:
Lightweight, customizable toast notifications for Angular 20+. A modern replacement for toastr with Angular Material design and flexible APIs.
126 lines (119 loc) • 15.2 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, ChangeDetectorRef, Input, ChangeDetectionStrategy, Component, ViewEncapsulation, Injectable } from '@angular/core';
import { MatSnackBarRef, MAT_SNACK_BAR_DATA, MatSnackBarAction, MatSnackBar } from '@angular/material/snack-bar';
import { interval } from 'rxjs';
class ProgressBar {
cdr = inject(ChangeDetectorRef);
duration = 2000; // ms, default value
progressValue = 100;
sub;
ngOnInit() {
const stepTime = 100; // ms
const totalSteps = (this.duration) / stepTime;
let currentStep = 0;
this.sub = interval(stepTime).subscribe(() => {
currentStep++;
this.progressValue = 100 - (currentStep / totalSteps) * 100;
this.cdr.markForCheck();
if (this.progressValue <= 0) {
this.progressValue = 0;
this.sub.unsubscribe();
}
});
}
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ProgressBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: ProgressBar, isStandalone: true, selector: "lib-progress-bar", inputs: { duration: "duration" }, ngImport: i0, template: "<div [style.width.%]=\"progressValue\" class=\"progress-inner\"></div>", styles: [".progress-inner{height:6px;overflow:hidden;background:#22212183;transition:width .3s linear}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ProgressBar, decorators: [{
type: Component,
args: [{ selector: 'lib-progress-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [style.width.%]=\"progressValue\" class=\"progress-inner\"></div>", styles: [".progress-inner{height:6px;overflow:hidden;background:#22212183;transition:width .3s linear}\n"] }]
}], propDecorators: { duration: [{
type: Input
}] } });
class Toast {
snackRef = inject(MatSnackBarRef);
data = inject(MAT_SNACK_BAR_DATA);
dismiss() {
this.snackRef.dismiss();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: Toast, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: Toast, isStandalone: true, selector: "lib-toast", ngImport: i0, template: "<div class=\"toast\">\n <span class=\"toast-icon\">\n\n @switch (data.type) {\n @case ('success') {\n <svg class=\"w-8 h-8\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\"\n viewBox=\"0 0 20 20\">\n <path\n d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z\" />\n </svg>\n }\n @case ('error') {\n <svg class=\"w-5 h-5\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\"\n viewBox=\"0 0 20 20\">\n <path\n d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 11.793a1 1 0 1 1-1.414 1.414L10 11.414l-2.293 2.293a1 1 0 0 1-1.414-1.414L8.586 10 6.293 7.707a1 1 0 0 1 1.414-1.414L10 8.586l2.293-2.293a1 1 0 0 1 1.414 1.414L11.414 10l2.293 2.293Z\" />\n </svg>\n }\n @case ('warning') {\n <svg class=\"w-5 h-5\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\"\n viewBox=\"0 0 16 16\">\n <path\n d=\"M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5m.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2\" />\n </svg>\n }\n @default {\n <svg class=\"w-5 h-5\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\"\n viewBox=\"0 0 20 20\">\n <path\n d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM10 15a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-4a1 1 0 0 1-2 0V6a1 1 0 0 1 2 0v5Z\" />\n </svg>\n }\n }\n\n </span>\n <div class=\"toast-message\">\n @if(data.title){\n <p style=\"font-size: 18px; margin: 0px 0 5px 0;\"> <strong>{{data.title}}</strong></p>\n }\n @if (data.message){\n <p style=\"font-size: 16px; margin: 0;\">{{data.message}}</p>\n }\n </div>\n @if (data.showClose){\n <button matSnackBarAction (click)=\"snackRef.dismissWithAction()\" type=\"button\" class=\"toast-close\"\n aria-label=\"Close\">\n <span aria-hidden=\"true\">×</span>\n </button>\n }\n</div>\n@if(data.progressBar){\n<span style=\"display: block; width: 100%; position: absolute; bottom: 0; left: 0;\">\n <lib-progress-bar [duration]=\"data.duration\" />\n</span>\n}", styles: [":root{--toast-success-bg: #51a351;--toast-success-text: white;--toast-info-bg: #2f96b4;--toast-info-text: white;--toast-warning-bg: #f89406;--toast-warning-text: white;--toast-error-bg: #bd362f;--toast-error-text: white}.dark-theme{--toast-success-bg: #51a351;--toast-success-text: white;--toast-info-bg: #2f96b4;--toast-info-text: white;--toast-warning-bg: #f89406;--toast-warning-text: white;--toast-error-bg: #bd362f;--toast-error-text: white}.info{--mat-snack-bar-container-color: var(--toast-info-bg);--mat-snack-bar-supporting-text-color: var(--toast-info-text);--mat-snack-bar-button-color: white}.success{--mat-snack-bar-container-color: var(--toast-success-bg);--mat-snack-bar-supporting-text-color: var(--toast-success-text);--mat-snack-bar-button-color: white}.warning{--mat-snack-bar-container-color: var(--toast-warning-bg);--mat-snack-bar-supporting-text-color: var(--toast-warning-text);--mat-snack-bar-button-color: white}.error{--mat-snack-bar-container-color: var(--toast-error-bg);--mat-snack-bar-supporting-text-color: var(--toast-error-text);--mat-snack-bar-button-color: white}.toast{position:relative;display:flex;align-items:center;font-family:Arial,Helvetica,sans-serif;min-height:65px;min-width:300px}.toast .toast-icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem}.toast .toast-icon svg{width:2rem;height:2rem}.toast .toast-message{margin-inline-start:.75rem;text-wrap:initial;max-width:270px}.toast .toast-close{position:absolute;top:0;right:0;margin-inline-end:-.6rem;margin-top:-.6rem;display:inline-block;width:1.5rem;height:1.5rem;border-radius:50%;background-color:transparent;border-color:transparent;font-size:1.3rem;color:#fff;display:inline-flex;align-items:center;justify-content:center}.toast .toast-close:hover{cursor:pointer;color:red;background-color:#f3f4f6}.toast .toast-close:focus{outline:none;box-shadow:0 0 0 2px #d1d5db}\n"], dependencies: [{ kind: "directive", type: MatSnackBarAction, selector: "[matSnackBarAction]" }, { kind: "component", type: ProgressBar, selector: "lib-progress-bar", inputs: ["duration"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: Toast, decorators: [{
type: Component,
args: [{ selector: 'lib-toast', imports: [MatSnackBarAction, ProgressBar], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"toast\">\n <span class=\"toast-icon\">\n\n @switch (data.type) {\n @case ('success') {\n <svg class=\"w-8 h-8\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\"\n viewBox=\"0 0 20 20\">\n <path\n d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z\" />\n </svg>\n }\n @case ('error') {\n <svg class=\"w-5 h-5\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\"\n viewBox=\"0 0 20 20\">\n <path\n d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 11.793a1 1 0 1 1-1.414 1.414L10 11.414l-2.293 2.293a1 1 0 0 1-1.414-1.414L8.586 10 6.293 7.707a1 1 0 0 1 1.414-1.414L10 8.586l2.293-2.293a1 1 0 0 1 1.414 1.414L11.414 10l2.293 2.293Z\" />\n </svg>\n }\n @case ('warning') {\n <svg class=\"w-5 h-5\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\"\n viewBox=\"0 0 16 16\">\n <path\n d=\"M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5m.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2\" />\n </svg>\n }\n @default {\n <svg class=\"w-5 h-5\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\"\n viewBox=\"0 0 20 20\">\n <path\n d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM10 15a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-4a1 1 0 0 1-2 0V6a1 1 0 0 1 2 0v5Z\" />\n </svg>\n }\n }\n\n </span>\n <div class=\"toast-message\">\n @if(data.title){\n <p style=\"font-size: 18px; margin: 0px 0 5px 0;\"> <strong>{{data.title}}</strong></p>\n }\n @if (data.message){\n <p style=\"font-size: 16px; margin: 0;\">{{data.message}}</p>\n }\n </div>\n @if (data.showClose){\n <button matSnackBarAction (click)=\"snackRef.dismissWithAction()\" type=\"button\" class=\"toast-close\"\n aria-label=\"Close\">\n <span aria-hidden=\"true\">×</span>\n </button>\n }\n</div>\n@if(data.progressBar){\n<span style=\"display: block; width: 100%; position: absolute; bottom: 0; left: 0;\">\n <lib-progress-bar [duration]=\"data.duration\" />\n</span>\n}", styles: [":root{--toast-success-bg: #51a351;--toast-success-text: white;--toast-info-bg: #2f96b4;--toast-info-text: white;--toast-warning-bg: #f89406;--toast-warning-text: white;--toast-error-bg: #bd362f;--toast-error-text: white}.dark-theme{--toast-success-bg: #51a351;--toast-success-text: white;--toast-info-bg: #2f96b4;--toast-info-text: white;--toast-warning-bg: #f89406;--toast-warning-text: white;--toast-error-bg: #bd362f;--toast-error-text: white}.info{--mat-snack-bar-container-color: var(--toast-info-bg);--mat-snack-bar-supporting-text-color: var(--toast-info-text);--mat-snack-bar-button-color: white}.success{--mat-snack-bar-container-color: var(--toast-success-bg);--mat-snack-bar-supporting-text-color: var(--toast-success-text);--mat-snack-bar-button-color: white}.warning{--mat-snack-bar-container-color: var(--toast-warning-bg);--mat-snack-bar-supporting-text-color: var(--toast-warning-text);--mat-snack-bar-button-color: white}.error{--mat-snack-bar-container-color: var(--toast-error-bg);--mat-snack-bar-supporting-text-color: var(--toast-error-text);--mat-snack-bar-button-color: white}.toast{position:relative;display:flex;align-items:center;font-family:Arial,Helvetica,sans-serif;min-height:65px;min-width:300px}.toast .toast-icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem}.toast .toast-icon svg{width:2rem;height:2rem}.toast .toast-message{margin-inline-start:.75rem;text-wrap:initial;max-width:270px}.toast .toast-close{position:absolute;top:0;right:0;margin-inline-end:-.6rem;margin-top:-.6rem;display:inline-block;width:1.5rem;height:1.5rem;border-radius:50%;background-color:transparent;border-color:transparent;font-size:1.3rem;color:#fff;display:inline-flex;align-items:center;justify-content:center}.toast .toast-close:hover{cursor:pointer;color:red;background-color:#f3f4f6}.toast .toast-close:focus{outline:none;box-shadow:0 0 0 2px #d1d5db}\n"] }]
}] });
class ToastService {
snackBar = inject(MatSnackBar);
commonConfig = {
duration: 2000,
horizontalPosition: 'right',
verticalPosition: 'top',
direction: 'ltr',
};
// default = info
defaultConfig = {
...this.commonConfig,
data: { type: 'info', message: '', showClose: true, duration: this.commonConfig.duration, progressBar: false },
};
sucessConfig = {
...this.commonConfig,
data: { type: 'success', message: '', showClose: true, duration: this.commonConfig.duration, progressBar: false }
};
warningConfig = {
...this.commonConfig,
data: { type: 'warning', message: '', showClose: true, duration: this.commonConfig.duration, progressBar: false }
};
errorConfig = {
...this.commonConfig,
data: { type: 'error', message: '', showClose: true, duration: this.commonConfig.duration, progressBar: false }
};
show(type, message, title, opts) {
const data = {
type,
message,
title,
showClose: opts?.showClose ?? true,
duration: opts?.duration ?? this.commonConfig.duration,
progressBar: opts?.progressBar ?? false,
};
const config = { ...this.defaultConfig, ...(opts ?? {}), data }; // override of default
config.panelClass = type;
return this.snackBar.openFromComponent(Toast, config);
}
info(message, title, opts) {
const infoCfg = { ...this.defaultConfig, ...(opts) ?? {} };
return this.show('info', message, title, infoCfg);
}
success(message, title, opts) {
const successCfg = { ...this.sucessConfig, ...(opts) ?? {} };
return this.show('success', message, title, successCfg);
}
warning(message, title, opts) {
const warningCfg = { ...this.warningConfig, ...(opts) ?? {} };
return this.show('warning', message, title, warningCfg);
}
error(message, title, opts) {
const errorCfg = { ...this.errorConfig, ...(opts) ?? {} };
return this.show('error', message, title, errorCfg);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ToastService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ToastService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}] });
/*
* Public API Surface of ngx-toastr-notifier
*/
/**
* Generated bundle index. Do not edit.
*/
export { ToastService };
//# sourceMappingURL=ngx-toastr-notifier.mjs.map