@progress/kendo-angular-notification
Version:
Kendo UI Notification for Angular
176 lines (175 loc) • 7.95 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, Input, ElementRef, ComponentFactoryResolver, ViewContainerRef, Renderer2, ViewChild, TemplateRef, NgZone, } from '@angular/core';
import { NotificationComponent } from './notification.component';
import { take } from 'rxjs/operators';
import * as i0 from "@angular/core";
/**
* @hidden
*/
export class NotificationContainerComponent {
element;
renderer;
resolver;
ngZone;
container;
group;
id = '';
notifications = [];
position;
constructor(element, renderer, resolver, ngZone) {
this.element = element;
this.renderer = renderer;
this.resolver = resolver;
this.ngZone = ngZone;
/**/
}
ngOnDestroy() {
this.notifications.forEach((notification) => {
if (notification.closeClickSubscription) {
notification.closeClickSubscription.unsubscribe();
}
});
this.notifications = [];
}
addNotification(settings) {
this.position = settings.position;
this.id = `${this.position.horizontal} ${this.position.vertical}`;
const factory = this.resolver.resolveComponentFactory(NotificationComponent);
const notificationRef = this.container.createComponent(factory);
this.applySettings(notificationRef, settings);
let customComponent = null;
if (typeof settings.content === 'function') {
const customFactory = this.resolver.resolveComponentFactory(settings.content);
customComponent = notificationRef.instance.container.createComponent(customFactory);
}
notificationRef.changeDetectorRef.detectChanges();
this.notifications.push(notificationRef.instance);
if (settings.appendTo) {
this.applyAbsolutePosition(settings.appendTo);
}
this.applyPosition();
this.applyContainerWrap();
return {
afterHide: notificationRef.instance.close,
hide: () => notificationRef.instance.hide(customComponent),
notification: notificationRef,
content: customComponent || null,
};
}
hide(notificationRef) {
const instance = notificationRef.instance;
const index = this.notifications.indexOf(instance);
this.notifications.splice(index, 1);
if (instance.closeClickSubscription) {
instance.closeClickSubscription.unsubscribe();
}
instance.templateRef = null;
instance.templateString = null;
notificationRef.destroy();
if (this.notifications.length > 0) {
this.ngZone.onStable
.asObservable()
.pipe(take(1))
.subscribe(() => {
this.applyPosition();
});
}
}
applyContainerWrap() {
const value = this.position.horizontal === 'right' ? 'wrap-reverse' : 'wrap';
this.renderer.setStyle(this.group.nativeElement, 'flex-wrap', value);
}
applySettings(notificationRef, settings) {
const notification = notificationRef.instance;
const content = settings.content;
const animation = settings.animation || null;
notification.closeClickSubscription = notification.close.subscribe(() => this.hide(notificationRef));
if (typeof content === 'string') {
notification.templateString = content;
}
if (content instanceof TemplateRef) {
notification.templateRef = content;
}
notification.animation = animation;
const type = settings.type;
if (type && type.style === undefined) {
type.style = 'none';
}
if (type && type.icon === undefined) {
type.icon = true;
}
notification.type = type;
notification.closeTitle = settings.closeTitle;
if (settings.cssClass) {
notification.cssClass = settings.cssClass;
}
if (settings.notificationLabel) {
notification.notificationLabel = settings.notificationLabel;
}
notification.closable = settings.closable;
notification.hideAfter = settings.hideAfter;
notification.width = settings.width;
notification.height = settings.height;
}
applyAbsolutePosition(appendToContainer) {
const appendTo = appendToContainer.element.nativeElement;
const el = this.element.nativeElement.children[0];
if (window.getComputedStyle(appendTo).position === 'static') {
this.renderer.setStyle(appendTo, 'position', 'relative');
}
this.renderer.setStyle(el, 'position', 'absolute');
}
applyPosition() {
const element = this.element.nativeElement.children[0];
const elementHalfWidth = element.getBoundingClientRect().width / 2;
const positionStyles = this.setContainerPosition(this.position, elementHalfWidth);
Object.keys(positionStyles).forEach((cssStyle) => {
element.style[cssStyle] = positionStyles[cssStyle];
});
}
setContainerPosition(position, offsetMargin) {
const positionLayout = {
horizontal: {
left: { left: 0, alignItems: 'flex-start' },
right: { right: 0, alignItems: 'flex-start' },
center: { left: '50%', marginLeft: `${-offsetMargin}px`, alignItems: 'center' },
},
vertical: {
top: { top: 0 },
bottom: { bottom: 0 },
},
};
const horizontal = positionLayout.horizontal[position.horizontal];
const vertical = positionLayout.vertical[position.vertical];
return Object.assign({}, horizontal, vertical);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NotificationContainerComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ComponentFactoryResolver }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NotificationContainerComponent, isStandalone: true, selector: "kendo-notification-container", inputs: { id: "id" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "group", first: true, predicate: ["group"], descendants: true, static: true }], ngImport: i0, template: `
<div #group class="k-notification-group">
<ng-container #container></ng-container>
</div>
`, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NotificationContainerComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-notification-container',
template: `
<div #group class="k-notification-group">
<ng-container #container></ng-container>
</div>
`,
standalone: true,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ComponentFactoryResolver }, { type: i0.NgZone }], propDecorators: { container: [{
type: ViewChild,
args: ['container', { read: ViewContainerRef, static: true }]
}], group: [{
type: ViewChild,
args: ['group', { static: true }]
}], id: [{
type: Input
}] } });