UNPKG

ngx-french-toast

Version:

<p align="center"> <img src="./projects/ngx-french-toast/logo.png" alt="ngx-french-toast logo" width="200px" /> </p>

459 lines (447 loc) 28.1 kB
import * as i0 from '@angular/core'; import { InjectionToken, inject, viewChild, ViewContainerRef, input, output, signal, HostListener, Component, DestroyRef, viewChildren, Injectable, NgModule, makeEnvironmentProviders } from '@angular/core'; import { filter, BehaviorSubject, Subject } from 'rxjs'; import { Overlay } from '@angular/cdk/overlay'; import { ComponentPortal } from '@angular/cdk/portal'; import { NgStyle } from '@angular/common'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; var ToastPosition; (function (ToastPosition) { ToastPosition["TOP_RIGHT"] = "top-right"; ToastPosition["BOTTOM_RIGHT"] = "bottom-right"; ToastPosition["TOP_LEFT"] = "top-left"; ToastPosition["BOTTOM_LEFT"] = "bottom-left"; })(ToastPosition || (ToastPosition = {})); var ToastType; (function (ToastType) { ToastType["SUCCESS"] = "success"; ToastType["DANGER"] = "danger"; ToastType["WARNING"] = "warning"; ToastType["INFO"] = "info"; })(ToastType || (ToastType = {})); const TOAST_CONFIG = new InjectionToken('TOAST_CONFIG'); // Generated by ChatGPT @ Jun 2023 function darkenHexColor(hexColor, factor) { // Remove the '#' symbol from the HEX color code hexColor = hexColor.replace('#', ''); // Convert the HEX color code to RGB values const r = parseInt(hexColor.substring(0, 2), 16); const g = parseInt(hexColor.substring(2, 4), 16); const b = parseInt(hexColor.substring(4, 6), 16); // Convert RGB to HSL const hsl = rgbToHsl(r, g, b); // Darken the lightness component const darkenedHsl = { ...hsl, l: hsl.l * factor }; // Add a small amount of black const blackFactor = 0.125; // Adjust the value to control the amount of black added const darkenedL = darkenedHsl.l * (1 - blackFactor); // Convert HSL back to RGB const rgb = hslToRgb(darkenedHsl.h, darkenedHsl.s, darkenedL); // Convert the RGB values back to HEX const darkenedHex = `#${padZero(rgb.r.toString(16))}${padZero(rgb.g.toString(16))}${padZero(rgb.b.toString(16))}`; return darkenedHex; } function rgbToHsl(r, g, b) { r /= 255; g /= 255; b /= 255; const max = Math.max(r, g, b); const min = Math.min(r, g, b); let h = 0, s = 0, l = (max + min) / 2; if (max !== min) { const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return { h, s, l }; } function hslToRgb(h, s, l) { let r, g, b; if (s === 0) { r = g = b = l; } else { const hue2rgb = (p, q, t) => { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; }; const q = l < 0.5 ? l * (1 + s) : l + s - l * s; const p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3) * 255; g = hue2rgb(p, q, h) * 255; b = hue2rgb(p, q, h - 1 / 3) * 255; } return { r: Math.round(r), g: Math.round(g), b: Math.round(b), }; } function padZero(hex) { return hex.length === 1 ? `0${hex}` : hex; } class ToastComponent { config = inject(TOAST_CONFIG); onClick(event) { event.stopPropagation(); } container = viewChild.required('container', { read: ViewContainerRef }); toast = input.required(...(ngDevMode ? [{ debugName: "toast" }] : [])); currentTheme = input(...(ngDevMode ? [undefined, { debugName: "currentTheme" }] : [])); control = output(); isVisible = signal(false, ...(ngDevMode ? [{ debugName: "isVisible" }] : [])); duration; remainingTime; timeout; resumeTime; component; svgUrlIsFromSprite = false; position = ToastPosition.BOTTOM_RIGHT; bottomRight = ToastPosition.BOTTOM_RIGHT; bottomLeft = ToastPosition.BOTTOM_LEFT; topRight = ToastPosition.TOP_RIGHT; topLeft = ToastPosition.TOP_LEFT; linearGradient = ''; toastConfig; timebarColor; textColor = ''; style = ''; constructor() { this.toastConfig = this.config; if (this.toastConfig.position) { this.position = this.toastConfig.position; } } ngAfterViewInit() { if (this.toast().component) { this.createDynamicToast(); } } ngOnInit() { this.getColors(); const toast = this.toast(); this.svgUrlIsFromSprite = toast.icon?.includes('.svg#'); if (toast?.infinite) return; this.duration = Number(toast.duration); this.remainingTime = Number(toast.duration); this.resumeTime = new Date(); this.timeout = setTimeout(() => { this.destroyToast(); }, this.duration); } ngAfterContentInit() { setTimeout(() => { this.isVisible.set(true); }, 10); } ngOnDestroy() { clearTimeout(this.timeout); } createDynamicToast() { this.container().clear(); this.component = this.container().createComponent(this.toast().component); this.component.instance.content = this.toast().content; const toast = this.toast(); if (toast?.context) { this.component.instance.context = toast.context; } } destroyToast() { this.isVisible.set(false); setTimeout(() => { this.control.emit(this.toast()); }, 100); } onMouseEnter() { if (this.toast()?.infinite) return; clearTimeout(this.timeout); const diff = new Date().getTime() - this.resumeTime.getTime(); this.remainingTime -= diff; } onMouseLeave() { if (this.toast()?.infinite) return; this.resumeTime = new Date(); this.timeout = setTimeout(() => { this.destroyToast(); }, this.remainingTime); } getColors() { this.getToastStyle(); this.getTimebarColor(); } getToastStyle() { this.textColor = this.getToastTextColor(); this.style = `--text-color: ${this.textColor};`; const colorHexCode = this.toastConfig?.colors?.[this.toast().type]; if (!colorHexCode) return; const darkenedColorHexCode = darkenHexColor(colorHexCode, 0.725); this.linearGradient = this.config.colors?.autoGradient ? `linear-gradient(45deg, ${darkenedColorHexCode}, ${colorHexCode})` : colorHexCode; this.style += `background: ${this.linearGradient}`; } getToastTextColor() { const toastTypeText = this.toast().type + 'Text'; const textColorHexCode = this.config.colors?.[toastTypeText] || '#ffffff'; return textColorHexCode; } getTimebarColor() { if (!this.toastConfig.colors?.timebar) return; this.timebarColor = { background: this.toastConfig.colors?.timebar }; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: ToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.4", type: ToastComponent, isStandalone: true, selector: "toast", inputs: { toast: { classPropertyName: "toast", publicName: "toast", isSignal: true, isRequired: true, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { control: "control" }, host: { listeners: { "click": "onClick($event)" } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<div\n class=\"toast-container\"\n [id]=\"toast()._id\"\n [style]=\"style\"\n [class.right]=\"position === bottomRight || position === topRight\"\n [class.left]=\"position === bottomLeft || position === topLeft\"\n [class.visible]=\"isVisible()\"\n [class]=\"toast().type\"\n [class.dynamic]=\"toast().component ? true : false\"\n (click)=\"toast().component ? null : destroyToast()\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n>\n @if (toast().component) {\n <div class=\"close\">\n <button class=\"icon\" (click)=\"destroyToast()\"></button>\n </div>\n }\n @if (!toast().infinite) {\n <div class=\"toast-timer\" [style]=\"'--animation-speed: ' + duration / 1000 + 's;'\" [ngStyle]=\"timebarColor\"></div>\n }\n <div class=\"toast-group\">\n @if (toast().icon) {\n <div class=\"toast-group__icon\">\n @if (svgUrlIsFromSprite) {\n <svg>\n <use [attr.xlink:href]=\"toast().icon\"></use>\n </svg>\n } @else {\n <img [src]=\"toast().icon\" />\n }\n </div>\n }\n <div class=\"toast-group__text\">\n <span class=\"toast-group__text--title\">{{ toast().title }}</span>\n @if (toast().component || toast().content) {\n @if (toast().component) {\n <ng-template #container />\n } @else {\n <span class=\"toast-group__text--content\">{{ toast().content }}</span>\n }\n }\n </div>\n </div>\n</div>\n", styles: [".toast-container{opacity:0;width:22.5rem;transition:all .3s;border-radius:8px;overflow:hidden;padding:.625rem 1rem;position:relative}@media screen and (max-width: 768px){.toast-container{width:100%}}.toast-container .close{position:absolute;top:.5rem;right:.5rem;display:flex;justify-content:center;align-items:center}.toast-container .close .icon{width:25px;height:25px;position:relative;display:flex;justify-content:center;align-items:center;border:0;outline:0;background:transparent;transition:all .3s;cursor:pointer}.toast-container .close .icon:hover{opacity:.5}.toast-container .close .icon:before,.toast-container .close .icon:after{content:\"\";position:absolute;width:15px;height:2px;background-color:var(--text-color);transform-origin:center}.toast-container .close .icon:before{transform:rotate(45deg)}.toast-container .close .icon:after{transform:rotate(-45deg)}.toast-container .toast-group{display:flex;gap:1rem}.toast-container .toast-group .toast-group__icon{display:flex;justify-content:flex-start;align-items:flex-start;height:max-content}.toast-container .toast-group .toast-group__text{display:flex;flex-direction:column;gap:2px}.toast-container .toast-group .toast-group__text .toast-group__text--title{font-size:var(--title-font-size);font-weight:600;color:var(--text-color);line-height:1.2rem}.toast-container .toast-group .toast-group__text .toast-group__text--content{font-size:var(--content-font-size);font-weight:500;color:var(--text-color);line-height:130%}.toast-container .toast-timer{height:4px;position:absolute;top:0;left:0;border-radius:8px;animation:widthAnimation var(--animation-speed) linear;background:linear-gradient(45deg,#2b6bbf,#10425b);animation-iteration-count:1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.toast-container:not(.dynamic){cursor:pointer}.toast-container.right{transform:translate(120%)}.toast-container.left{transform:translate(-120%)}.toast-container.visible{transform:translate(0);opacity:1}.toast-container.visible:hover{opacity:.9}.toast-container.visible:hover .toast-timer{animation-play-state:paused}@keyframes widthAnimation{0%{width:0%}to{width:100%}}.toast-container.danger{background:linear-gradient(45deg,#d10303,#f77676)}.toast-container.success{background:linear-gradient(45deg,#00bd6e,#58d77c)}.toast-container.info{background:linear-gradient(45deg,#5b9dcb,#9cd1f7)}.toast-container.warning{background:linear-gradient(45deg,#f58802,#ffc600)}.toast-container svg{color:var(--text-color);fill:var(--text-color);width:1rem;height:1rem}.toast-container img{width:1rem}\n", "*,*:after,*:before{font-family:var(--font-family);box-sizing:border-box;padding:0;margin:0}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: ToastComponent, decorators: [{ type: Component, args: [{ selector: 'toast', imports: [NgStyle], template: "<div\n class=\"toast-container\"\n [id]=\"toast()._id\"\n [style]=\"style\"\n [class.right]=\"position === bottomRight || position === topRight\"\n [class.left]=\"position === bottomLeft || position === topLeft\"\n [class.visible]=\"isVisible()\"\n [class]=\"toast().type\"\n [class.dynamic]=\"toast().component ? true : false\"\n (click)=\"toast().component ? null : destroyToast()\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n>\n @if (toast().component) {\n <div class=\"close\">\n <button class=\"icon\" (click)=\"destroyToast()\"></button>\n </div>\n }\n @if (!toast().infinite) {\n <div class=\"toast-timer\" [style]=\"'--animation-speed: ' + duration / 1000 + 's;'\" [ngStyle]=\"timebarColor\"></div>\n }\n <div class=\"toast-group\">\n @if (toast().icon) {\n <div class=\"toast-group__icon\">\n @if (svgUrlIsFromSprite) {\n <svg>\n <use [attr.xlink:href]=\"toast().icon\"></use>\n </svg>\n } @else {\n <img [src]=\"toast().icon\" />\n }\n </div>\n }\n <div class=\"toast-group__text\">\n <span class=\"toast-group__text--title\">{{ toast().title }}</span>\n @if (toast().component || toast().content) {\n @if (toast().component) {\n <ng-template #container />\n } @else {\n <span class=\"toast-group__text--content\">{{ toast().content }}</span>\n }\n }\n </div>\n </div>\n</div>\n", styles: [".toast-container{opacity:0;width:22.5rem;transition:all .3s;border-radius:8px;overflow:hidden;padding:.625rem 1rem;position:relative}@media screen and (max-width: 768px){.toast-container{width:100%}}.toast-container .close{position:absolute;top:.5rem;right:.5rem;display:flex;justify-content:center;align-items:center}.toast-container .close .icon{width:25px;height:25px;position:relative;display:flex;justify-content:center;align-items:center;border:0;outline:0;background:transparent;transition:all .3s;cursor:pointer}.toast-container .close .icon:hover{opacity:.5}.toast-container .close .icon:before,.toast-container .close .icon:after{content:\"\";position:absolute;width:15px;height:2px;background-color:var(--text-color);transform-origin:center}.toast-container .close .icon:before{transform:rotate(45deg)}.toast-container .close .icon:after{transform:rotate(-45deg)}.toast-container .toast-group{display:flex;gap:1rem}.toast-container .toast-group .toast-group__icon{display:flex;justify-content:flex-start;align-items:flex-start;height:max-content}.toast-container .toast-group .toast-group__text{display:flex;flex-direction:column;gap:2px}.toast-container .toast-group .toast-group__text .toast-group__text--title{font-size:var(--title-font-size);font-weight:600;color:var(--text-color);line-height:1.2rem}.toast-container .toast-group .toast-group__text .toast-group__text--content{font-size:var(--content-font-size);font-weight:500;color:var(--text-color);line-height:130%}.toast-container .toast-timer{height:4px;position:absolute;top:0;left:0;border-radius:8px;animation:widthAnimation var(--animation-speed) linear;background:linear-gradient(45deg,#2b6bbf,#10425b);animation-iteration-count:1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.toast-container:not(.dynamic){cursor:pointer}.toast-container.right{transform:translate(120%)}.toast-container.left{transform:translate(-120%)}.toast-container.visible{transform:translate(0);opacity:1}.toast-container.visible:hover{opacity:.9}.toast-container.visible:hover .toast-timer{animation-play-state:paused}@keyframes widthAnimation{0%{width:0%}to{width:100%}}.toast-container.danger{background:linear-gradient(45deg,#d10303,#f77676)}.toast-container.success{background:linear-gradient(45deg,#00bd6e,#58d77c)}.toast-container.info{background:linear-gradient(45deg,#5b9dcb,#9cd1f7)}.toast-container.warning{background:linear-gradient(45deg,#f58802,#ffc600)}.toast-container svg{color:var(--text-color);fill:var(--text-color);width:1rem;height:1rem}.toast-container img{width:1rem}\n", "*,*:after,*:before{font-family:var(--font-family);box-sizing:border-box;padding:0;margin:0}\n"] }] }], ctorParameters: () => [], propDecorators: { onClick: [{ type: HostListener, args: ['click', ['$event']] }] } }); class ToastsComponent { toastService = inject(ToastService); config = inject(TOAST_CONFIG); destroyRef = inject(DestroyRef); toastsComponents = viewChildren(ToastComponent, ...(ngDevMode ? [{ debugName: "toastsComponents" }] : [])); toasts = signal([], ...(ngDevMode ? [{ debugName: "toasts" }] : [])); position = ToastPosition.BOTTOM_RIGHT; bottomRight = ToastPosition.BOTTOM_RIGHT; bottomLeft = ToastPosition.BOTTOM_LEFT; topRight = ToastPosition.TOP_RIGHT; topLeft = ToastPosition.TOP_LEFT; fontFamily = ''; titleFontSize = ''; contentFontSize = ''; style = ''; componentRef; constructor() { if (this.config.position) this.position = this.config.position; } ngOnInit() { this.getToasts(); this.style = this.getStyles(); } getStyles() { this.fontFamily = `--font-family: ${this.config.font?.family || 'sans-serif'}`; this.titleFontSize = `--title-font-size: ${this.config.font?.titleFontSize || '1.2rem'}`; this.contentFontSize = `--content-font-size: ${this.config.font?.contentFontSize || '1rem'}`; return `${this.fontFamily}; ${this.titleFontSize}; ${this.contentFontSize}`; } getToasts() { this.listenForToasts(); this.listenForDestroyAllToasts(); this.listenForDestroyToast(); } listenForToasts() { this.toastService.toast .pipe(filter((toast) => !!toast), takeUntilDestroyed(this.destroyRef)) .subscribe({ next: (toast) => { const toastElement = { ...toast }; const currentToasts = this.toasts(); const limit = this.config.limit || 3; const updatedToasts = [...currentToasts, toastElement]; this.toasts.set(updatedToasts); if (updatedToasts.length > limit) { setTimeout(() => { const allToastsArePinned = currentToasts.every((t) => t.pinned); const toastToRemove = allToastsArePinned ? updatedToasts[0] : updatedToasts.find((t) => !t.pinned); if (toastToRemove) { this.toastsComponents() .find((comp) => comp.toast()._uId === toastToRemove._uId) ?.destroyToast(); } }, 100); } } }); } listenForDestroyAllToasts() { this.toastService.clearAll.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ next: () => { const toastsComponents = this.toastsComponents(); if (!toastsComponents) return; toastsComponents.forEach((e) => { e.destroyToast(); }); } }); } listenForDestroyToast() { this.toastService.clearToast.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ next: (uniqueId) => { this.toastsComponents() .find((toast) => toast.toast()._uId === uniqueId) ?.destroyToast(); } }); } control(toast) { const toasts = this.toasts(); const index = toasts.indexOf(toast); toasts[index].isVisible = false; toasts.splice(index, 1); this.toasts.set(toasts); if (this.toasts().length === 0) { this.componentRef.destroy(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: ToastsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.4", type: ToastsComponent, isStandalone: true, selector: "french-toast", viewQueries: [{ propertyName: "toastsComponents", predicate: ToastComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (toasts().length) {\n <div\n class=\"toasts-container\"\n [style]=\"style\"\n [class.bottom-right]=\"position === bottomRight\"\n [class.bottom-left]=\"position === bottomLeft\"\n [class.top-left]=\"position === topLeft\"\n [class.top-right]=\"position === topRight\"\n >\n @for (toast of toasts(); track toast._id) {\n @if (toast?.isVisible) {\n <toast [toast]=\"toast\" (control)=\"control($event)\" />\n }\n }\n </div>\n}\n", styles: [".toasts-container{position:fixed;display:flex;gap:.5rem;z-index:1050;padding:1rem}@media screen and (max-width: 768px){.toasts-container{width:100%}}.toasts-container.bottom-right{bottom:0rem;right:0rem;flex-direction:column}.toasts-container.bottom-left{bottom:0rem;left:0rem;flex-direction:column}.toasts-container.top-right{top:0rem;right:0rem;flex-direction:column-reverse}.toasts-container.top-left{top:0rem;left:0rem;flex-direction:column-reverse}\n", "*,*:after,*:before{font-family:var(--font-family);box-sizing:border-box;padding:0;margin:0}\n"], dependencies: [{ kind: "component", type: ToastComponent, selector: "toast", inputs: ["toast", "currentTheme"], outputs: ["control"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: ToastsComponent, decorators: [{ type: Component, args: [{ selector: 'french-toast', imports: [ToastComponent], template: "@if (toasts().length) {\n <div\n class=\"toasts-container\"\n [style]=\"style\"\n [class.bottom-right]=\"position === bottomRight\"\n [class.bottom-left]=\"position === bottomLeft\"\n [class.top-left]=\"position === topLeft\"\n [class.top-right]=\"position === topRight\"\n >\n @for (toast of toasts(); track toast._id) {\n @if (toast?.isVisible) {\n <toast [toast]=\"toast\" (control)=\"control($event)\" />\n }\n }\n </div>\n}\n", styles: [".toasts-container{position:fixed;display:flex;gap:.5rem;z-index:1050;padding:1rem}@media screen and (max-width: 768px){.toasts-container{width:100%}}.toasts-container.bottom-right{bottom:0rem;right:0rem;flex-direction:column}.toasts-container.bottom-left{bottom:0rem;left:0rem;flex-direction:column}.toasts-container.top-right{top:0rem;right:0rem;flex-direction:column-reverse}.toasts-container.top-left{top:0rem;left:0rem;flex-direction:column-reverse}\n", "*,*:after,*:before{font-family:var(--font-family);box-sizing:border-box;padding:0;margin:0}\n"] }] }], ctorParameters: () => [] }); class ToastService { config = inject(TOAST_CONFIG); overlay = inject(Overlay); overlayRef; duration = 7000; toast = new BehaviorSubject(null); clearAll = new Subject(); clearToast = new Subject(); constructor() { if (this.config?.defaultDuration) { this.duration = this.config.defaultDuration; } } addToast(toastInput, type) { const newToast = { _id: toastInput._id, title: toastInput.title, content: toastInput.content, isVisible: true, duration: toastInput.duration, icon: toastInput?.icon ?? null, type, component: toastInput.component, infinite: toastInput.infinite, pinned: toastInput.pinned, context: toastInput.context, _uId: this.getUniqueId(6) }; this.toast.next(newToast); if (!this.overlayRef?.hasAttached()) this.createOverlay(); } createOverlay() { this.overlayRef = this.overlay.create(); const toastPortal = new ComponentPortal(ToastsComponent); const componentRef = this.overlayRef.attach(toastPortal); componentRef.instance.componentRef = componentRef; } handleToast(toastInput, type) { toastInput._id = toastInput?._id ?? this.getUniqueId(5); toastInput.duration = toastInput?.duration ?? this.duration; this.addToast(toastInput, type); } success(toastInput) { this.handleToast(toastInput, ToastType.SUCCESS); } danger(toastInput) { this.handleToast(toastInput, ToastType.DANGER); } info(toastInput) { this.handleToast(toastInput, ToastType.INFO); } warning(toastInput) { this.handleToast(toastInput, ToastType.WARNING); } clearAllToasts() { this.clearAll.next(); } destroyToast(toastComponent) { this.clearToast.next(toastComponent.toast()._uId); } getUniqueId(parts) { const stringArr = []; for (let i = 0; i < parts; i++) { // tslint:disable-next-line:no-bitwise const S4 = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); stringArr.push(S4); } return stringArr.join(''); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: ToastService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: ToastService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); class FrenchToastModule { static forRoot(config) { if (!config) { config = { position: ToastPosition.BOTTOM_RIGHT, defaultDuration: 10000, colors: { autoGradient: false } }; } return { ngModule: FrenchToastModule, providers: [ { provide: TOAST_CONFIG, useValue: config } ] }; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: FrenchToastModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.2.4", ngImport: i0, type: FrenchToastModule }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: FrenchToastModule }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: FrenchToastModule, decorators: [{ type: NgModule, args: [{}] }] }); const provideFrenchToast = (config = {}) => { const providers = [ { provide: TOAST_CONFIG, useValue: config } ]; return makeEnvironmentProviders(providers); }; /* * Public API Surface of ngx-french-toast */ /** * Generated bundle index. Do not edit. */ export { FrenchToastModule, ToastComponent, ToastPosition, ToastService, ToastType, ToastsComponent, provideFrenchToast }; //# sourceMappingURL=ngx-french-toast.mjs.map