@progress/kendo-angular-notification
Version:
Kendo UI Notification for Angular
138 lines (137 loc) • 5.98 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 { Injectable, ComponentFactoryResolver, ApplicationRef, Injector, InjectionToken, ElementRef, Inject, Optional } from '@angular/core';
import { NotificationContainerComponent } from '../notification.container.component';
import * as i0 from "@angular/core";
/**
* Injects the Notification container. When not provided, uses the first root component of
* the application.
*
* > Use `NOTIFICATION_CONTAINER` only with the [`NotificationService`]({% slug api_notification_notificationservice %}) class.
*
* @example
*
* ```ts
* import { NgModule, ElementRef } from '@angular/core';
* import { BrowserModule } from '@angular/platform-browser';
* import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
*
* import { NotificationModule, NOTIFICATION_CONTAINER } from '@progress/kendo-angular-notification';
* import { AppComponent } from './app.component';
*
* @NgModule({
* declarations: [AppComponent],
* imports: [BrowserModule, NotificationModule],
* bootstrap: [AppComponent],
* providers: [
* {
* provide: NOTIFICATION_CONTAINER,
* useFactory: () => ({ nativeElement: document.body } as ElementRef)
* }
* ]
* })
* export class AppModule {}
*
* platformBrowserDynamic().bootstrapModule(AppModule);
* ```
*/
export const NOTIFICATION_CONTAINER = new InjectionToken('Notification Container');
/**
* A service for opening Notification components dynamically
* ([see example]({% slug overview_notification %})).
*
* @export
* @class NotificationService
*/
export class NotificationService {
resolver;
injector;
container;
notificationContainers = [];
position = { horizontal: 'right', vertical: 'top' };
applicationRef;
/**
* @hidden
*/
constructor(resolver, injector, container) {
this.resolver = resolver;
this.injector = injector;
this.container = container;
}
/**
* Opens a Notification component. Created Notifications are mounted
* in the DOM directly in the root application component.
*
* @param {NotificationSettings} settings - The settings which define the Notification.
*
* @returns {NotificationRef} - A reference to the Notification object and the convenience properties.
*/
show(settings) {
if (!settings) {
throw new Error('NotificationSettings settings are required');
}
const target = this.findGroupContainer(settings);
const position = settings.position || this.position;
const currentId = `${position.horizontal} ${position.vertical}`;
let container;
let notificationRef;
let notificationContainer = this.notificationContainers.find(c => target.nativeElement.contains(c.element.nativeElement) && c.id === currentId);
if (!notificationContainer) {
container = this.resolver
.resolveComponentFactory(NotificationContainerComponent)
.create(this.injector);
notificationContainer = container.instance;
this.appRef.attachView(container.hostView);
const hostViewElement = container.location.nativeElement;
const groupContainer = this.findGroupContainer(settings);
if (!groupContainer) {
throw new Error(`
View Container not found! Inject the NOTIFICATION_CONTAINER or define a specific ViewContainerRef via
the appendTo option. See https://www.telerik.com/kendo-angular-ui/components/notification/api/NOTIFICATION_CONTAINER/
for more details.
`);
}
groupContainer.nativeElement.appendChild(hostViewElement);
this.notificationContainers.push(notificationContainer);
}
settings.position = position;
// eslint-disable-next-line prefer-const
notificationRef = notificationContainer.addNotification(settings);
return notificationRef;
}
get appRef() {
if (!this.applicationRef) {
this.applicationRef = this.injector.get(ApplicationRef);
}
return this.applicationRef;
}
findGroupContainer(settings) {
let container;
if (settings.appendTo) {
container = settings.appendTo.element;
}
else if (this.container) {
container = this.container;
}
else {
const appRoot = this.appRef.components && this.appRef.components[0];
container = appRoot ? appRoot.location : null;
}
return container;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NotificationService, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.Injector }, { token: NOTIFICATION_CONTAINER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NotificationService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NotificationService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return [{ type: i0.ComponentFactoryResolver }, { type: i0.Injector }, { type: i0.ElementRef, decorators: [{
type: Inject,
args: [NOTIFICATION_CONTAINER]
}, {
type: Optional
}] }]; } });