UNPKG

primeng

Version:

PrimeNG is an open source UI library for Angular featuring a rich set of 80+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeB

1,011 lines (963 loc) 41.2 kB
import { trigger, state, transition, style, animate, query, animateChild } from '@angular/animations'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { Injectable, EventEmitter, inject, numberAttribute, ViewChild, Output, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, booleanAttribute, ContentChildren, ContentChild, NgModule } from '@angular/core'; import { uuid, isEmpty, setAttribute } from '@primeuix/utils'; import { SharedModule, MessageService, PrimeTemplate } from 'primeng/api'; import { BaseComponent } from 'primeng/basecomponent'; import { CheckIcon, ExclamationTriangleIcon, InfoCircleIcon, TimesIcon, TimesCircleIcon } from 'primeng/icons'; import { ZIndexUtils } from 'primeng/utils'; import { BaseStyle } from 'primeng/base'; const theme = ({ dt }) => ` .p-toast { width: ${dt('toast.width')}; white-space: pre-line; word-break: break-word; } .p-toast-message { margin: 0 0 1rem 0; } .p-toast-message-icon { flex-shrink: 0; font-size: ${dt('toast.icon.size')}; width: ${dt('toast.icon.size')}; height: ${dt('toast.icon.size')}; } .p-toast-message-content { display: flex; align-items: flex-start; padding: ${dt('toast.content.padding')}; gap: ${dt('toast.content.gap')}; } .p-toast-message-text { flex: 1 1 auto; display: flex; flex-direction: column; gap: ${dt('toast.text.gap')}; } .p-toast-summary { font-weight: ${dt('toast.summary.font.weight')}; font-size: ${dt('toast.summary.font.size')}; } .p-toast-detail { font-weight: ${dt('toast.detail.font.weight')}; font-size: ${dt('toast.detail.font.size')}; } .p-toast-close-button { display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; cursor: pointer; background: transparent; transition: background ${dt('toast.transition.duration')}, color ${dt('toast.transition.duration')}, outline-color ${dt('toast.transition.duration')}, box-shadow ${dt('toast.transition.duration')}; outline-color: transparent; color: inherit; width: ${dt('toast.close.button.width')}; height: ${dt('toast.close.button.height')}; border-radius: ${dt('toast.close.button.border.radius')}; margin: -25% 0 0 0; right: -25%; padding: 0; border: none; user-select: none; } .p-toast-close-button:dir(rtl) { margin: -25% 0 0 auto; left: -25%; right: auto; } .p-toast-message-info, .p-toast-message-success, .p-toast-message-warn, .p-toast-message-error, .p-toast-message-secondary, .p-toast-message-contrast { border-width: ${dt('toast.border.width')}; border-style: solid; backdrop-filter: blur(${dt('toast.blur')}); border-radius: ${dt('toast.border.radius')}; } .p-toast-close-icon { font-size: ${dt('toast.close.icon.size')}; width: ${dt('toast.close.icon.size')}; height: ${dt('toast.close.icon.size')}; } .p-toast-close-button:focus-visible { outline-width: ${dt('focus.ring.width')}; outline-style: ${dt('focus.ring.style')}; outline-offset: ${dt('focus.ring.offset')}; } .p-toast-message-info { background: ${dt('toast.info.background')}; border-color: ${dt('toast.info.border.color')}; color: ${dt('toast.info.color')}; box-shadow: ${dt('toast.info.shadow')}; } .p-toast-message-info .p-toast-detail { color: ${dt('toast.info.detail.color')}; } .p-toast-message-info .p-toast-close-button:focus-visible { outline-color: ${dt('toast.info.close.button.focus.ring.color')}; box-shadow: ${dt('toast.info.close.button.focus.ring.shadow')}; } .p-toast-message-info .p-toast-close-button:hover { background: ${dt('toast.info.close.button.hover.background')}; } .p-toast-message-success { background: ${dt('toast.success.background')}; border-color: ${dt('toast.success.border.color')}; color: ${dt('toast.success.color')}; box-shadow: ${dt('toast.success.shadow')}; } .p-toast-message-success .p-toast-detail { color: ${dt('toast.success.detail.color')}; } .p-toast-message-success .p-toast-close-button:focus-visible { outline-color: ${dt('toast.success.close.button.focus.ring.color')}; box-shadow: ${dt('toast.success.close.button.focus.ring.shadow')}; } .p-toast-message-success .p-toast-close-button:hover { background: ${dt('toast.success.close.button.hover.background')}; } .p-toast-message-warn { background: ${dt('toast.warn.background')}; border-color: ${dt('toast.warn.border.color')}; color: ${dt('toast.warn.color')}; box-shadow: ${dt('toast.warn.shadow')}; } .p-toast-message-warn .p-toast-detail { color: ${dt('toast.warn.detail.color')}; } .p-toast-message-warn .p-toast-close-button:focus-visible { outline-color: ${dt('toast.warn.close.button.focus.ring.color')}; box-shadow: ${dt('toast.warn.close.button.focus.ring.shadow')}; } .p-toast-message-warn .p-toast-close-button:hover { background: ${dt('toast.warn.close.button.hover.background')}; } .p-toast-message-error { background: ${dt('toast.error.background')}; border-color: ${dt('toast.error.border.color')}; color: ${dt('toast.error.color')}; box-shadow: ${dt('toast.error.shadow')}; } .p-toast-message-error .p-toast-detail { color: ${dt('toast.error.detail.color')}; } .p-toast-message-error .p-toast-close-button:focus-visible { outline-color: ${dt('toast.error.close.button.focus.ring.color')}; box-shadow: ${dt('toast.error.close.button.focus.ring.shadow')}; } .p-toast-message-error .p-toast-close-button:hover { background: ${dt('toast.error.close.button.hover.background')}; } .p-toast-message-secondary { background: ${dt('toast.secondary.background')}; border-color: ${dt('toast.secondary.border.color')}; color: ${dt('toast.secondary.color')}; box-shadow: ${dt('toast.secondary.shadow')}; } .p-toast-message-secondary .p-toast-detail { color: ${dt('toast.secondary.detail.color')}; } .p-toast-message-secondary .p-toast-close-button:focus-visible { outline-color: ${dt('toast.secondary.close.button.focus.ring.color')}; box-shadow: ${dt('toast.secondary.close.button.focus.ring.shadow')}; } .p-toast-message-secondary .p-toast-close-button:hover { background: ${dt('toast.secondary.close.button.hover.background')}; } .p-toast-message-contrast { background: ${dt('toast.contrast.background')}; border-color: ${dt('toast.contrast.border.color')}; color: ${dt('toast.contrast.color')}; box-shadow: ${dt('toast.contrast.shadow')}; } .p-toast-message-contrast .p-toast-detail { color: ${dt('toast.contrast.detail.color')}; } .p-toast-message-contrast .p-toast-close-button:focus-visible { outline-color: ${dt('toast.contrast.close.button.focus.ring.color')}; box-shadow: ${dt('toast.contrast.close.button.focus.ring.shadow')}; } .p-toast-message-contrast .p-toast-close-button:hover { background: ${dt('toast.contrast.close.button.hover.background')}; } .p-toast-top-center { transform: translateX(-50%); } .p-toast-bottom-center { transform: translateX(-50%); } .p-toast-center { min-width: 20vw; transform: translate(-50%, -50%); } .p-toast-message-enter-from { opacity: 0; transform: translateY(50%); } .p-toast-message-leave-from { max-height: 1000px; } .p-toast .p-toast-message.p-toast-message-leave-to { max-height: 0; opacity: 0; margin-bottom: 0; overflow: hidden; } .p-toast-message-enter-active { transition: transform 0.3s, opacity 0.3s; } .p-toast-message-leave-active { transition: max-height 0.45s cubic-bezier(0, 1, 0, 1), opacity 0.3s, margin-bottom 0.3s; } `; // Position const inlineStyles = { root: ({ instance }) => { const { _position } = instance; return { position: 'fixed', top: _position === 'top-right' || _position === 'top-left' || _position === 'top-center' ? '20px' : _position === 'center' ? '50%' : null, right: (_position === 'top-right' || _position === 'bottom-right') && '20px', bottom: (_position === 'bottom-left' || _position === 'bottom-right' || _position === 'bottom-center') && '20px', left: _position === 'top-left' || _position === 'bottom-left' ? '20px' : _position === 'center' || _position === 'top-center' || _position === 'bottom-center' ? '50%' : null }; } }; const classes = { root: ({ instance }) => ({ 'p-toast p-component': true, [`p-toast-${instance._position}`]: !!instance._position }), message: ({ instance }) => ({ 'p-toast-message': true, 'p-toast-message-info': instance.message.severity === 'info' || instance.message.severity === undefined, 'p-toast-message-warn': instance.message.severity === 'warn', 'p-toast-message-error': instance.message.severity === 'error', 'p-toast-message-success': instance.message.severity === 'success', 'p-toast-message-secondary': instance.message.severity === 'secondary', 'p-toast-message-contrast': instance.message.severity === 'contrast' }), messageContent: 'p-toast-message-content', messageIcon: ({ instance }) => ({ 'p-toast-message-icon': true, [`pi ${instance.message.icon}`]: !!instance.message.icon }), messageText: 'p-toast-message-text', summary: 'p-toast-summary', detail: 'p-toast-detail', closeButton: 'p-toast-close-button', closeIcon: ({ instance }) => ({ 'p-toast-close-icon': true, [`pi ${instance.message.closeIcon}`]: !!instance.message.closeIcon }) }; class ToastStyle extends BaseStyle { name = 'toast'; theme = theme; classes = classes; inlineStyles = inlineStyles; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ToastStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ToastStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ToastStyle, decorators: [{ type: Injectable }] }); /** * * Toast is used to display messages in an overlay. * * [Live Demo](https://www.primeng.org/toast/) * * @module toaststyle * */ var ToastClasses; (function (ToastClasses) { /** * Class name of the root element */ ToastClasses["root"] = "p-toast"; /** * Class name of the message element */ ToastClasses["message"] = "p-toast-message"; /** * Class name of the message content element */ ToastClasses["messageContent"] = "p-toast-message-content"; /** * Class name of the message icon element */ ToastClasses["messageIcon"] = "p-toast-message-icon"; /** * Class name of the message text element */ ToastClasses["messageText"] = "p-toast-message-text"; /** * Class name of the summary element */ ToastClasses["summary"] = "p-toast-summary"; /** * Class name of the detail element */ ToastClasses["detail"] = "p-toast-detail"; /** * Class name of the close button element */ ToastClasses["closeButton"] = "p-toast-close-button"; /** * Class name of the close icon element */ ToastClasses["closeIcon"] = "p-toast-close-icon"; })(ToastClasses || (ToastClasses = {})); class ToastItem extends BaseComponent { zone; message; index; life; template; headlessTemplate; showTransformOptions; hideTransformOptions; showTransitionOptions; hideTransitionOptions; onClose = new EventEmitter(); containerViewChild; _componentStyle = inject(ToastStyle); timeout; constructor(zone) { super(); this.zone = zone; } ngAfterViewInit() { super.ngAfterViewInit(); this.initTimeout(); } initTimeout() { if (!this.message?.sticky) { this.zone.runOutsideAngular(() => { this.timeout = setTimeout(() => { this.onClose.emit({ index: this.index, message: this.message }); }, this.message?.life || this.life || 3000); }); } } clearTimeout() { if (this.timeout) { clearTimeout(this.timeout); this.timeout = null; } } onMouseEnter() { this.clearTimeout(); } onMouseLeave() { this.initTimeout(); } onCloseIconClick = (event) => { this.clearTimeout(); this.onClose.emit({ index: this.index, message: this.message }); event.preventDefault(); }; get closeAriaLabel() { return this.config.translation.aria ? this.config.translation.aria.close : undefined; } ngOnDestroy() { this.clearTimeout(); super.ngOnDestroy(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ToastItem, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: ToastItem, isStandalone: true, selector: "p-toastItem", inputs: { message: "message", index: ["index", "index", numberAttribute], life: ["life", "life", numberAttribute], template: "template", headlessTemplate: "headlessTemplate", showTransformOptions: "showTransformOptions", hideTransformOptions: "hideTransformOptions", showTransitionOptions: "showTransitionOptions", hideTransitionOptions: "hideTransitionOptions" }, outputs: { onClose: "onClose" }, providers: [ToastStyle], viewQueries: [{ propertyName: "containerViewChild", first: true, predicate: ["container"], descendants: true }], usesInheritance: true, ngImport: i0, template: ` <div #container [attr.id]="message?.id" [class]="message?.styleClass" [ngClass]="cx('message')" [@messageState]="{ value: 'visible', params: { showTransformParams: showTransformOptions, hideTransformParams: hideTransformOptions, showTransitionParams: showTransitionOptions, hideTransitionParams: hideTransitionOptions } }" (mouseenter)="onMouseEnter()" (mouseleave)="onMouseLeave()" role="alert" aria-live="assertive" aria-atomic="true" [attr.data-pc-name]="'toast'" [attr.data-pc-section]="'root'" > @if (headlessTemplate) { <ng-container *ngTemplateOutlet="headlessTemplate; context: { $implicit: message, closeFn: onCloseIconClick }"></ng-container> } @else { <div [ngClass]="cx('messageContent')" [class]="message?.contentStyleClass" [attr.data-pc-section]="'content'"> <ng-container *ngIf="!template"> <span *ngIf="message.icon" [ngClass]="cx('messageIcon')"></span> <span [ngClass]="cx('messageIcon')" *ngIf="!message.icon" [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'"> @switch (message.severity) { @case ('success') { <CheckIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } @case ('info') { <InfoCircleIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } @case ('error') { <TimesCircleIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } @case ('warn') { <ExclamationTriangleIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } @default { <InfoCircleIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } } </span> <div [ngClass]="cx('messageText')" [attr.data-pc-section]="'text'"> <div [ngClass]="cx('summary')" [attr.data-pc-section]="'summary'"> {{ message.summary }} </div> <div [ngClass]="cx('detail')" [attr.data-pc-section]="'detail'">{{ message.detail }}</div> </div> </ng-container> <ng-container *ngTemplateOutlet="template; context: { $implicit: message }"></ng-container> @if (message?.closable !== false) { <div> <button type="button" [attr.class]="cx('closeButton')" (click)="onCloseIconClick($event)" (keydown.enter)="onCloseIconClick($event)" [ariaLabel]="closeAriaLabel" [attr.data-pc-section]="'closebutton'" autofocus> @if (message.closeIcon) { <span *ngIf="message.closeIcon" [ngClass]="cx('closeIcon')"></span> } @else { <TimesIcon [ngClass]="cx('closeIcon')" [attr.aria-hidden]="true" [attr.data-pc-section]="'closeicon'" /> } </button> </div> } </div> } </div> `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CheckIcon, selector: "CheckIcon" }, { kind: "component", type: ExclamationTriangleIcon, selector: "ExclamationTriangleIcon" }, { kind: "component", type: InfoCircleIcon, selector: "InfoCircleIcon" }, { kind: "component", type: TimesIcon, selector: "TimesIcon" }, { kind: "component", type: TimesCircleIcon, selector: "TimesCircleIcon" }, { kind: "ngmodule", type: SharedModule }], animations: [ trigger('messageState', [ state('visible', style({ transform: 'translateY(0)', opacity: 1 })), transition('void => *', [ style({ transform: '{{showTransformParams}}', opacity: 0 }), animate('{{showTransitionParams}}') ]), transition('* => void', [ animate('{{hideTransitionParams}}', style({ height: 0, opacity: 0, transform: '{{hideTransformParams}}' })) ]) ]) ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ToastItem, decorators: [{ type: Component, args: [{ selector: 'p-toastItem', standalone: true, imports: [CommonModule, CheckIcon, ExclamationTriangleIcon, InfoCircleIcon, TimesIcon, TimesCircleIcon, SharedModule], template: ` <div #container [attr.id]="message?.id" [class]="message?.styleClass" [ngClass]="cx('message')" [@messageState]="{ value: 'visible', params: { showTransformParams: showTransformOptions, hideTransformParams: hideTransformOptions, showTransitionParams: showTransitionOptions, hideTransitionParams: hideTransitionOptions } }" (mouseenter)="onMouseEnter()" (mouseleave)="onMouseLeave()" role="alert" aria-live="assertive" aria-atomic="true" [attr.data-pc-name]="'toast'" [attr.data-pc-section]="'root'" > @if (headlessTemplate) { <ng-container *ngTemplateOutlet="headlessTemplate; context: { $implicit: message, closeFn: onCloseIconClick }"></ng-container> } @else { <div [ngClass]="cx('messageContent')" [class]="message?.contentStyleClass" [attr.data-pc-section]="'content'"> <ng-container *ngIf="!template"> <span *ngIf="message.icon" [ngClass]="cx('messageIcon')"></span> <span [ngClass]="cx('messageIcon')" *ngIf="!message.icon" [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'"> @switch (message.severity) { @case ('success') { <CheckIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } @case ('info') { <InfoCircleIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } @case ('error') { <TimesCircleIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } @case ('warn') { <ExclamationTriangleIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } @default { <InfoCircleIcon [attr.aria-hidden]="true" [attr.data-pc-section]="'icon'" /> } } </span> <div [ngClass]="cx('messageText')" [attr.data-pc-section]="'text'"> <div [ngClass]="cx('summary')" [attr.data-pc-section]="'summary'"> {{ message.summary }} </div> <div [ngClass]="cx('detail')" [attr.data-pc-section]="'detail'">{{ message.detail }}</div> </div> </ng-container> <ng-container *ngTemplateOutlet="template; context: { $implicit: message }"></ng-container> @if (message?.closable !== false) { <div> <button type="button" [attr.class]="cx('closeButton')" (click)="onCloseIconClick($event)" (keydown.enter)="onCloseIconClick($event)" [ariaLabel]="closeAriaLabel" [attr.data-pc-section]="'closebutton'" autofocus> @if (message.closeIcon) { <span *ngIf="message.closeIcon" [ngClass]="cx('closeIcon')"></span> } @else { <TimesIcon [ngClass]="cx('closeIcon')" [attr.aria-hidden]="true" [attr.data-pc-section]="'closeicon'" /> } </button> </div> } </div> } </div> `, animations: [ trigger('messageState', [ state('visible', style({ transform: 'translateY(0)', opacity: 1 })), transition('void => *', [ style({ transform: '{{showTransformParams}}', opacity: 0 }), animate('{{showTransitionParams}}') ]), transition('* => void', [ animate('{{hideTransitionParams}}', style({ height: 0, opacity: 0, transform: '{{hideTransformParams}}' })) ]) ]) ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ToastStyle] }] }], ctorParameters: () => [{ type: i0.NgZone }], propDecorators: { message: [{ type: Input }], index: [{ type: Input, args: [{ transform: numberAttribute }] }], life: [{ type: Input, args: [{ transform: numberAttribute }] }], template: [{ type: Input }], headlessTemplate: [{ type: Input }], showTransformOptions: [{ type: Input }], hideTransformOptions: [{ type: Input }], showTransitionOptions: [{ type: Input }], hideTransitionOptions: [{ type: Input }], onClose: [{ type: Output }], containerViewChild: [{ type: ViewChild, args: ['container'] }] } }); /** * Toast is used to display messages in an overlay. * @group Components */ class Toast extends BaseComponent { /** * Key of the message in case message is targeted to a specific toast component. * @group Props */ key; /** * Whether to automatically manage layering. * @group Props */ autoZIndex = true; /** * Base zIndex value to use in layering. * @group Props */ baseZIndex = 0; /** * The default time to display messages for in milliseconds. * @group Props */ life = 3000; /** * Inline style of the component. * @group Props */ style; /** * Inline class of the component. * @group Props */ styleClass; /** * Position of the toast in viewport. * @group Props */ get position() { return this._position; } set position(value) { this._position = value; this.cd.markForCheck(); } /** * It does not add the new message if there is already a toast displayed with the same content * @group Props */ preventOpenDuplicates = false; /** * Displays only once a message with the same content. * @group Props */ preventDuplicates = false; /** * Transform options of the show animation. * @group Props */ showTransformOptions = 'translateY(100%)'; /** * Transform options of the hide animation. * @group Props */ hideTransformOptions = 'translateY(-100%)'; /** * Transition options of the show animation. * @group Props */ showTransitionOptions = '300ms ease-out'; /** * Transition options of the hide animation. * @group Props */ hideTransitionOptions = '250ms ease-in'; /** * Object literal to define styles per screen size. * @group Props */ breakpoints; /** * Callback to invoke when a message is closed. * @param {ToastCloseEvent} event - custom close event. * @group Emits */ onClose = new EventEmitter(); /** * Custom template of message. * @group Templates */ template; /** * Custom headless template. * @group Templates */ headlessTemplate; containerViewChild; messageSubscription; clearSubscription; messages; messagesArchieve; _position = 'top-right'; messageService = inject(MessageService); _componentStyle = inject(ToastStyle); styleElement; id = uuid('pn_id_'); templates; ngOnInit() { super.ngOnInit(); this.messageSubscription = this.messageService.messageObserver.subscribe((messages) => { if (messages) { if (Array.isArray(messages)) { const filteredMessages = messages.filter((m) => this.canAdd(m)); this.add(filteredMessages); } else if (this.canAdd(messages)) { this.add([messages]); } } }); this.clearSubscription = this.messageService.clearObserver.subscribe((key) => { if (key) { if (this.key === key) { this.messages = null; } } else { this.messages = null; } this.cd.markForCheck(); }); } _template; _headlessTemplate; ngAfterContentInit() { this.templates?.forEach((item) => { switch (item.getType()) { case 'message': this._template = item.template; break; case 'headless': this._headlessTemplate = item.template; break; default: this._template = item.template; break; } }); } ngAfterViewInit() { super.ngAfterViewInit(); if (this.breakpoints) { this.createStyle(); } } add(messages) { this.messages = this.messages ? [...this.messages, ...messages] : [...messages]; if (this.preventDuplicates) { this.messagesArchieve = this.messagesArchieve ? [...this.messagesArchieve, ...messages] : [...messages]; } this.cd.markForCheck(); } canAdd(message) { let allow = this.key === message.key; if (allow && this.preventOpenDuplicates) { allow = !this.containsMessage(this.messages, message); } if (allow && this.preventDuplicates) { allow = !this.containsMessage(this.messagesArchieve, message); } return allow; } containsMessage(collection, message) { if (!collection) { return false; } return (collection.find((m) => { return m.summary === message.summary && m.detail == message.detail && m.severity === message.severity; }) != null); } onMessageClose(event) { this.messages?.splice(event.index, 1); this.onClose.emit({ message: event.message }); this.cd.detectChanges(); } onAnimationStart(event) { if (event.fromState === 'void') { this.renderer.setAttribute(this.containerViewChild?.nativeElement, this.id, ''); if (this.autoZIndex && this.containerViewChild?.nativeElement.style.zIndex === '') { ZIndexUtils.set('modal', this.containerViewChild?.nativeElement, this.baseZIndex || this.config.zIndex.modal); } } } onAnimationEnd(event) { if (event.toState === 'void') { if (this.autoZIndex && isEmpty(this.messages)) { ZIndexUtils.clear(this.containerViewChild?.nativeElement); } } } createStyle() { if (!this.styleElement) { this.styleElement = this.renderer.createElement('style'); this.styleElement.type = 'text/css'; this.renderer.appendChild(this.document.head, this.styleElement); let innerHTML = ''; for (let breakpoint in this.breakpoints) { let breakpointStyle = ''; for (let styleProp in this.breakpoints[breakpoint]) { breakpointStyle += styleProp + ':' + this.breakpoints[breakpoint][styleProp] + ' !important;'; } innerHTML += ` @media screen and (max-width: ${breakpoint}) { .p-toast[${this.id}] { ${breakpointStyle} } } `; } this.renderer.setProperty(this.styleElement, 'innerHTML', innerHTML); setAttribute(this.styleElement, 'nonce', this.config?.csp()?.nonce); } } destroyStyle() { if (this.styleElement) { this.renderer.removeChild(this.document.head, this.styleElement); this.styleElement = null; } } ngOnDestroy() { if (this.messageSubscription) { this.messageSubscription.unsubscribe(); } if (this.containerViewChild && this.autoZIndex) { ZIndexUtils.clear(this.containerViewChild.nativeElement); } if (this.clearSubscription) { this.clearSubscription.unsubscribe(); } this.destroyStyle(); super.ngOnDestroy(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: Toast, deps: null, target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "19.2.10", type: Toast, isStandalone: true, selector: "p-toast", inputs: { key: "key", autoZIndex: ["autoZIndex", "autoZIndex", booleanAttribute], baseZIndex: ["baseZIndex", "baseZIndex", numberAttribute], life: ["life", "life", numberAttribute], style: "style", styleClass: "styleClass", position: "position", preventOpenDuplicates: ["preventOpenDuplicates", "preventOpenDuplicates", booleanAttribute], preventDuplicates: ["preventDuplicates", "preventDuplicates", booleanAttribute], showTransformOptions: "showTransformOptions", hideTransformOptions: "hideTransformOptions", showTransitionOptions: "showTransitionOptions", hideTransitionOptions: "hideTransitionOptions", breakpoints: "breakpoints" }, outputs: { onClose: "onClose" }, providers: [ToastStyle], queries: [{ propertyName: "template", first: true, predicate: ["message"], descendants: true }, { propertyName: "headlessTemplate", first: true, predicate: ["headless"], descendants: true }, { propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "containerViewChild", first: true, predicate: ["container"], descendants: true }], usesInheritance: true, ngImport: i0, template: ` <div #container [ngClass]="cx('root')" [ngStyle]="sx('root')" [style]="style" [class]="styleClass"> <p-toastItem *ngFor="let msg of messages; let i = index" [message]="msg" [index]="i" [life]="life" (onClose)="onMessageClose($event)" [template]="template || _template" [headlessTemplate]="headlessTemplate || _headlessTemplate" @toastAnimation (@toastAnimation.start)="onAnimationStart($event)" (@toastAnimation.done)="onAnimationEnd($event)" [showTransformOptions]="showTransformOptions" [hideTransformOptions]="hideTransformOptions" [showTransitionOptions]="showTransitionOptions" [hideTransitionOptions]="hideTransitionOptions" ></p-toastItem> </div> `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ToastItem, selector: "p-toastItem", inputs: ["message", "index", "life", "template", "headlessTemplate", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onClose"] }, { kind: "ngmodule", type: SharedModule }], animations: [trigger('toastAnimation', [transition(':enter, :leave', [query('@*', animateChild())])])], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: Toast, decorators: [{ type: Component, args: [{ selector: 'p-toast', standalone: true, imports: [CommonModule, ToastItem, SharedModule], template: ` <div #container [ngClass]="cx('root')" [ngStyle]="sx('root')" [style]="style" [class]="styleClass"> <p-toastItem *ngFor="let msg of messages; let i = index" [message]="msg" [index]="i" [life]="life" (onClose)="onMessageClose($event)" [template]="template || _template" [headlessTemplate]="headlessTemplate || _headlessTemplate" @toastAnimation (@toastAnimation.start)="onAnimationStart($event)" (@toastAnimation.done)="onAnimationEnd($event)" [showTransformOptions]="showTransformOptions" [hideTransformOptions]="hideTransformOptions" [showTransitionOptions]="showTransitionOptions" [hideTransitionOptions]="hideTransitionOptions" ></p-toastItem> </div> `, animations: [trigger('toastAnimation', [transition(':enter, :leave', [query('@*', animateChild())])])], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [ToastStyle] }] }], propDecorators: { key: [{ type: Input }], autoZIndex: [{ type: Input, args: [{ transform: booleanAttribute }] }], baseZIndex: [{ type: Input, args: [{ transform: numberAttribute }] }], life: [{ type: Input, args: [{ transform: numberAttribute }] }], style: [{ type: Input }], styleClass: [{ type: Input }], position: [{ type: Input }], preventOpenDuplicates: [{ type: Input, args: [{ transform: booleanAttribute }] }], preventDuplicates: [{ type: Input, args: [{ transform: booleanAttribute }] }], showTransformOptions: [{ type: Input }], hideTransformOptions: [{ type: Input }], showTransitionOptions: [{ type: Input }], hideTransitionOptions: [{ type: Input }], breakpoints: [{ type: Input }], onClose: [{ type: Output }], template: [{ type: ContentChild, args: ['message'] }], headlessTemplate: [{ type: ContentChild, args: ['headless'] }], containerViewChild: [{ type: ViewChild, args: ['container'] }], templates: [{ type: ContentChildren, args: [PrimeTemplate] }] } }); class ToastModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ToastModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.10", ngImport: i0, type: ToastModule, imports: [Toast, SharedModule], exports: [Toast, SharedModule] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ToastModule, imports: [Toast, SharedModule, SharedModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: ToastModule, decorators: [{ type: NgModule, args: [{ imports: [Toast, SharedModule], exports: [Toast, SharedModule] }] }] }); /** * Generated bundle index. Do not edit. */ export { Toast, ToastClasses, ToastItem, ToastModule, ToastStyle }; //# sourceMappingURL=primeng-toast.mjs.map