@hxui/angular
Version:
* * *
1,569 lines (1,546 loc) • 944 kB
JavaScript
import { Directive, ElementRef, NgModule, InjectionToken, Inject, Injectable, Component, Input, ChangeDetectorRef, HostListener, ViewChild, Output, EventEmitter, forwardRef, NgZone, ComponentFactoryResolver, ViewContainerRef, Optional, TemplateRef, ContentChild, HostBinding, Injector, SecurityContext, ReflectiveInjector, Renderer2, IterableDiffers, ViewEncapsulation, CUSTOM_ELEMENTS_SCHEMA, Pipe, defineInjectable, inject, INJECTOR, ApplicationRef } from '@angular/core';
import { Subject, Observable, from } from 'rxjs';
import { DOCUMENT, CommonModule } from '@angular/common';
import { DomSanitizer, BrowserModule } from '@angular/platform-browser';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { takeUntil, take, debounceTime as debounceTime$1, mergeMap, filter, toArray } from 'rxjs/operators';
import { Subject as Subject$1, Subscription, fromEvent } from 'rxjs/index';
import { TemplatePortal, ComponentPortal, PortalModule } from '@angular/cdk/portal';
import { Overlay, ScrollDispatcher, OverlayModule } from '@angular/cdk/overlay';
import { isEqual, cloneDeep } from 'lodash';
import { debounceTime } from 'rxjs/internal/operators';
import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS, NgControl } from '@angular/forms';
import * as moment_ from 'moment';
import { Directionality } from '@angular/cdk/bidi';
import { __decorate } from 'tslib';
import { FocusTrapFactory, A11yModule } from '@angular/cdk/a11y';
import sortBy from 'array-sort-by';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class ToastrContainerDirective {
/**
* @param {?} el
*/
constructor(el) {
this.el = el;
}
/**
* @return {?}
*/
getContainerElement() {
return this.el.nativeElement;
}
}
ToastrContainerDirective.decorators = [
{ type: Directive, args: [{
selector: '[hxaToastrContainer]',
exportAs: 'hxaToastrContainer',
},] },
];
/** @nocollapse */
ToastrContainerDirective.ctorParameters = () => [
{ type: ElementRef }
];
class ToastrContainerModule {
}
ToastrContainerModule.decorators = [
{ type: NgModule, args: [{
declarations: [ToastrContainerDirective],
exports: [ToastrContainerDirective],
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @enum {number} */
const ToastrPosition = {
CENTER_CENTER: 0,
TOP_CENTER: 1,
BOTTOM_CENTER: 2,
TOP_FULL_WIDTH: 3,
BOTTOM_FULL_WIDTH: 4,
TOP_LEFT: 5,
TOP_RIGHT: 6,
BOTTOM_LEFT: 7,
BOTTOM_RIGHT: 8,
};
ToastrPosition[ToastrPosition.CENTER_CENTER] = 'CENTER_CENTER';
ToastrPosition[ToastrPosition.TOP_CENTER] = 'TOP_CENTER';
ToastrPosition[ToastrPosition.BOTTOM_CENTER] = 'BOTTOM_CENTER';
ToastrPosition[ToastrPosition.TOP_FULL_WIDTH] = 'TOP_FULL_WIDTH';
ToastrPosition[ToastrPosition.BOTTOM_FULL_WIDTH] = 'BOTTOM_FULL_WIDTH';
ToastrPosition[ToastrPosition.TOP_LEFT] = 'TOP_LEFT';
ToastrPosition[ToastrPosition.TOP_RIGHT] = 'TOP_RIGHT';
ToastrPosition[ToastrPosition.BOTTOM_LEFT] = 'BOTTOM_LEFT';
ToastrPosition[ToastrPosition.BOTTOM_RIGHT] = 'BOTTOM_RIGHT';
/**
* Everything a toast needs to launch
*/
class ToastPackage {
/**
* @param {?} toastId
* @param {?} config
* @param {?} message
* @param {?} title
* @param {?} toastType
* @param {?} toastRef
*/
constructor(toastId, config, message, title, toastType, toastRef) {
this.toastId = toastId;
this.config = config;
this.message = message;
this.title = title;
this.toastType = toastType;
this.toastRef = toastRef;
this._onTap = new Subject();
this._onAction = new Subject();
this.toastRef.afterClosed().subscribe(() => {
this._onAction.complete();
this._onTap.complete();
});
}
/**
* Fired on click
* @return {?}
*/
triggerTap() {
this._onTap.next();
if (this.config.tapToDismiss) {
this._onTap.complete();
}
}
/**
* @return {?}
*/
onTap() {
return this._onTap.asObservable();
}
/**
* available for use in custom toast
* @param {?=} action
* @return {?}
*/
triggerAction(action) {
this._onAction.next(action);
}
/**
* @return {?}
*/
onAction() {
return this._onAction.asObservable();
}
}
/** @type {?} */
const DefaultNoComponentGlobalConfig = {
maxOpened: 0,
autoDismiss: false,
newestOnTop: true,
preventDuplicates: false,
resetTimeoutOnDuplicate: false,
iconClasses: {
none: '',
error: 'is-error',
info: 'is-info',
success: 'is-success',
warning: 'is-warning',
},
// Individual
closeButton: false,
disableTimeOut: false,
timeOut: 5000,
extendedTimeOut: 1000,
enableHtml: false,
progressBar: false,
toastClass: 'hx-alert',
position: ToastrPosition.TOP_RIGHT,
titleClass: 'toast-title',
messageClass: 'toast-message',
easing: 'ease-in',
easeTime: 300,
tapToDismiss: true,
onActivateTick: false,
progressAnimation: 'decreasing',
};
/** @type {?} */
const TOAST_CONFIG = new InjectionToken('ToastrConfig');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* A `ComponentPortal` is a portal that instantiates some Component upon attachment.
* @template T
*/
class ComponentPortal$1 {
/**
* @param {?} component
* @param {?} injector
*/
constructor(component, injector) {
this.component = component;
this.injector = injector;
}
/**
* Attach this portal to a host.
* @param {?} host
* @param {?} newestOnTop
* @return {?}
*/
attach(host, newestOnTop) {
this._attachedHost = host;
return host.attach(this, newestOnTop);
}
/**
* Detach this portal from its host
* @return {?}
*/
detach() {
/** @type {?} */
const host = this._attachedHost;
if (host) {
this._attachedHost = undefined;
return host.detach();
}
}
/**
* Whether this portal is attached to a host.
* @return {?}
*/
get isAttached() {
return this._attachedHost != null;
}
/**
* Sets the PortalHost reference without performing `attach()`. This is used directly by
* the PortalHost when it is performing an `attach()` or `detach()`.
* @param {?=} host
* @return {?}
*/
setAttachedHost(host) {
this._attachedHost = host;
}
}
/**
* Partial implementation of PortalHost that only deals with attaching a
* ComponentPortal
* @abstract
*/
class BasePortalHost {
/**
* @param {?} portal
* @param {?} newestOnTop
* @return {?}
*/
attach(portal, newestOnTop) {
this._attachedPortal = portal;
return this.attachComponentPortal(portal, newestOnTop);
}
/**
* @return {?}
*/
detach() {
if (this._attachedPortal) {
this._attachedPortal.setAttachedHost();
}
this._attachedPortal = undefined;
if (this._disposeFn) {
this._disposeFn();
this._disposeFn = undefined;
}
}
/**
* @param {?} fn
* @return {?}
*/
setDisposeFn(fn) {
this._disposeFn = fn;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* A PortalHost for attaching portals to an arbitrary DOM element outside of the Angular
* application context.
*
* This is the only part of the portal core that directly touches the DOM.
*/
class DomPortalHost extends BasePortalHost {
/**
* @param {?} _hostDomElement
* @param {?} _componentFactoryResolver
* @param {?} _appRef
*/
constructor(_hostDomElement, _componentFactoryResolver, _appRef) {
super();
this._hostDomElement = _hostDomElement;
this._componentFactoryResolver = _componentFactoryResolver;
this._appRef = _appRef;
}
/**
* Attach the given ComponentPortal to DOM element using the ComponentFactoryResolver.
* @template T
* @param {?} portal Portal to be attached
* @param {?} newestOnTop
* @return {?}
*/
attachComponentPortal(portal, newestOnTop) {
/** @type {?} */
const componentFactory = this._componentFactoryResolver.resolveComponentFactory(portal.component);
/** @type {?} */
let componentRef;
// If the portal specifies a ViewContainerRef, we will use that as the attachment point
// for the component (in terms of Angular's component tree, not rendering).
// When the ViewContainerRef is missing, we use the factory to create the component directly
// and then manually attach the ChangeDetector for that component to the application (which
// happens automatically when using a ViewContainer).
componentRef = componentFactory.create(portal.injector);
// When creating a component outside of a ViewContainer, we need to manually register
// its ChangeDetector with the application. This API is unfortunately not yet published
// in Angular core. The change detector must also be deregistered when the component
// is destroyed to prevent memory leaks.
this._appRef.attachView(componentRef.hostView);
this.setDisposeFn(() => {
this._appRef.detachView(componentRef.hostView);
componentRef.destroy();
});
// At this point the component has been instantiated, so we move it to the location in the DOM
// where we want it to be rendered.
if (newestOnTop) {
this._hostDomElement.insertBefore(this._getComponentRootNode(componentRef), this._hostDomElement.firstChild);
}
else {
this._hostDomElement.appendChild(this._getComponentRootNode(componentRef));
}
return componentRef;
}
/**
* Gets the root HTMLElement for an instantiated component.
* @param {?} componentRef
* @return {?}
*/
_getComponentRootNode(componentRef) {
return (/** @type {?} */ (((/** @type {?} */ (componentRef.hostView))).rootNodes[0]));
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* Container inside which all toasts will render.
*/
class OverlayContainer {
/**
* @param {?} _document
*/
constructor(_document) {
this._document = _document;
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this._containerElement && this._containerElement.parentNode) {
this._containerElement.parentNode.removeChild(this._containerElement);
}
}
/**
* This method returns the overlay container element. It will lazily
* create the element the first time it is called to facilitate using
* the container in non-browser environments.
* @return {?} the container element
*/
getContainerElement() {
if (!this._containerElement) {
this._createContainer();
}
return this._containerElement;
}
/**
* Create the overlay container element, which is simply a div
* with the 'cdk-overlay-container' class on the document body.
* @return {?}
*/
_createContainer() {
/** @type {?} */
const container = this._document.createElement('div');
container.classList.add('overlay-container');
this._document.body.appendChild(container);
this._containerElement = container;
}
}
OverlayContainer.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] },
];
/** @nocollapse */
OverlayContainer.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
/** @nocollapse */ OverlayContainer.ngInjectableDef = defineInjectable({ factory: function OverlayContainer_Factory() { return new OverlayContainer(inject(DOCUMENT)); }, token: OverlayContainer, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* Reference to an overlay that has been created with the Overlay service.
* Used to manipulate or dispose of said overlay.
*/
class OverlayRef {
/**
* @param {?} _portalHost
*/
constructor(_portalHost) {
this._portalHost = _portalHost;
}
/**
* @param {?} portal
* @param {?=} newestOnTop
* @return {?}
*/
attach(portal, newestOnTop = true) {
return this._portalHost.attach(portal, newestOnTop);
}
/**
* Detaches an overlay from a portal.
* @return {?} Resolves when the overlay has been detached.
*/
detach() {
return this._portalHost.detach();
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* Service to create Overlays. Overlays are dynamically added pieces of floating UI, meant to be
* used as a low-level building building block for other components. Dialogs, tooltips, menus,
* selects, etc. can all be built using overlays. The service should primarily be used by authors
* of re-usable components rather than developers building end-user applications.
*
* An overlay *is* a PortalHost, so any kind of Portal can be loaded into one.
*/
class Overlay$1 {
/**
* @param {?} _overlayContainer
* @param {?} _componentFactoryResolver
* @param {?} _appRef
* @param {?} _document
*/
constructor(_overlayContainer, _componentFactoryResolver, _appRef, _document) {
this._overlayContainer = _overlayContainer;
this._componentFactoryResolver = _componentFactoryResolver;
this._appRef = _appRef;
this._document = _document;
// Namespace panes by overlay container
this._paneElements = new Map();
}
/**
* Creates an overlay.
* @param {?=} position
* @param {?=} overlayContainer
* @return {?} A reference to the created overlay.
*/
create(position, overlayContainer) {
// get existing pane if possible
return this._createOverlayRef(this.getPaneElement(position, overlayContainer));
}
/**
* @param {?=} position
* @param {?=} overlayContainer
* @return {?}
*/
getPaneElement(position = ToastrPosition.TOP_RIGHT, overlayContainer) {
if (!this._paneElements.get(overlayContainer)) {
this._paneElements.set(overlayContainer, {});
}
if (!this._paneElements.get(overlayContainer)[position]) {
this._paneElements.get(overlayContainer)[position] = this._createPaneElement(position, overlayContainer);
}
return this._paneElements.get(overlayContainer)[position];
}
/**
* Creates the DOM element for an overlay and appends it to the overlay container.
* @param {?} position
* @param {?=} overlayContainer
* @return {?} Newly-created pane element
*/
_createPaneElement(position, overlayContainer) {
/** @type {?} */
const pane = this._document.createElement('div');
pane.id = 'hxa-toastr-container';
/// pane.classList.add(positionClass);
pane.classList.add('hxa-toastr-container');
pane.classList.add('hxui-reset');
pane.style.position = 'fixed';
pane.style['z-index'] = 1000;
if (position === ToastrPosition.CENTER_CENTER) {
pane.style.top = '50%';
pane.style.left = '50%';
pane.style.transform = 'translate(-50%, -50%)';
}
else if (position === ToastrPosition.TOP_CENTER) {
pane.style.top = '0';
pane.style.right = '0';
pane.style.width = '100%';
}
else if (position === ToastrPosition.BOTTOM_CENTER) {
pane.style.bottom = '0';
pane.style.right = '0';
pane.style.width = '100%';
}
else if (position === ToastrPosition.TOP_FULL_WIDTH) {
pane.style.top = '0';
pane.style.right = '0';
pane.style.width = '100%';
}
else if (position === ToastrPosition.BOTTOM_FULL_WIDTH) {
pane.style.bottom = '0';
pane.style.right = '0';
pane.style.width = '100%';
}
else if (position === ToastrPosition.TOP_LEFT) {
pane.style.top = '2rem';
pane.style.left = '2rem';
}
else if (position === ToastrPosition.TOP_RIGHT) {
pane.style.top = '2rem';
pane.style.right = '2rem';
}
else if (position === ToastrPosition.BOTTOM_RIGHT) {
pane.style.bottom = '2rem';
pane.style.right = '2rem';
}
else if (position === ToastrPosition.BOTTOM_LEFT) {
pane.style.bottom = '2rem';
pane.style.left = '2rem';
}
if (!overlayContainer) {
this._overlayContainer.getContainerElement().appendChild(pane);
}
else {
overlayContainer.getContainerElement().appendChild(pane);
}
return pane;
}
/**
* Create a DomPortalHost into which the overlay content can be loaded.
* @param {?} pane The DOM element to turn into a portal host.
* @return {?} A portal host for the given DOM element.
*/
_createPortalHost(pane) {
return new DomPortalHost(pane, this._componentFactoryResolver, this._appRef);
}
/**
* Creates an OverlayRef for an overlay in the given DOM element.
* @param {?} pane DOM element for the overlay
* @return {?}
*/
_createOverlayRef(pane) {
return new OverlayRef(this._createPortalHost(pane));
}
}
Overlay$1.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] },
];
/** @nocollapse */
Overlay$1.ctorParameters = () => [
{ type: OverlayContainer },
{ type: ComponentFactoryResolver },
{ type: ApplicationRef },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
/** @nocollapse */ Overlay$1.ngInjectableDef = defineInjectable({ factory: function Overlay_Factory() { return new Overlay$1(inject(OverlayContainer), inject(ComponentFactoryResolver), inject(ApplicationRef), inject(DOCUMENT)); }, token: Overlay$1, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* Reference to a toast opened via the Toastr service.
* @template T
*/
class ToastrRef {
/**
* @param {?} _overlayRef
*/
constructor(_overlayRef) {
this._overlayRef = _overlayRef;
/**
* Subject for notifying the user that the toast has finished closing.
*/
this._afterClosed = new Subject();
/**
* triggered when toast is activated
*/
this._activate = new Subject();
/**
* notifies the toast that it should close before the timeout
*/
this._manualClose = new Subject();
/**
* notifies the toast that it should reset the timeouts
*/
this._resetTimeout = new Subject();
}
/**
* @return {?}
*/
manualClose() {
this._manualClose.next();
this._manualClose.complete();
}
/**
* @return {?}
*/
manualClosed() {
return this._manualClose.asObservable();
}
/**
* @return {?}
*/
timeoutReset() {
return this._resetTimeout.asObservable();
}
/**
* Close the toast.
* @return {?}
*/
close() {
this._overlayRef.detach();
this._afterClosed.next();
this._manualClose.next();
this._afterClosed.complete();
this._manualClose.complete();
this._activate.complete();
this._resetTimeout.complete();
}
/**
* Gets an observable that is notified when the toast is finished closing.
* @return {?}
*/
afterClosed() {
return this._afterClosed.asObservable();
}
/**
* @return {?}
*/
isInactive() {
return this._activate.isStopped;
}
/**
* @return {?}
*/
activate() {
this._activate.next();
this._activate.complete();
}
/**
* Gets an observable that is notified when the toast has started opening.
* @return {?}
*/
afterActivate() {
return this._activate.asObservable();
}
/**
* Reset the toast timouts
* @return {?}
*/
resetTimeout() {
this._resetTimeout.next();
}
}
/**
* Custom injector type specifically for instantiating components with a toast.
*/
class ToastrInjector {
/**
* @param {?} _toastPackage
* @param {?} _parentInjector
*/
constructor(_toastPackage, _parentInjector) {
this._toastPackage = _toastPackage;
this._parentInjector = _parentInjector;
}
/**
* @template T
* @param {?} token
* @param {?=} notFoundValue
* @param {?=} flags
* @return {?}
*/
get(token, notFoundValue, flags) {
if (token === ToastPackage) {
return this._toastPackage;
}
return this._parentInjector.get(token, notFoundValue, flags);
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class ToastrService {
/**
* @param {?} token
* @param {?} overlay
* @param {?} _injector
* @param {?} sanitizer
* @param {?} ngZone
*/
constructor(token, overlay, _injector, sanitizer, ngZone) {
this.overlay = overlay;
this._injector = _injector;
this.sanitizer = sanitizer;
this.ngZone = ngZone;
this.currentlyActive = 0;
this.toasts = [];
this.index = 0;
this.toastrConfig = Object.assign({}, token.default, token.config);
if (token.config.iconClasses) {
this.toastrConfig.iconClasses = Object.assign({}, token.default.iconClasses, token.config.iconClasses);
}
}
/**
* show toast
* @param {?=} message
* @param {?=} title
* @param {?=} override
* @param {?=} type
* @return {?}
*/
show(message, title, override = {}, type = '') {
return this._preBuildNotification(type, message, title, this.applyConfig(override));
}
/**
* show successful toast
* @param {?=} message
* @param {?=} title
* @param {?=} override
* @return {?}
*/
success(message, title, override = {}) {
/** @type {?} */
const type = this.toastrConfig.iconClasses.success || '';
return this._preBuildNotification(type, message, title, this.applyConfig(override));
}
/**
* show error toast
* @param {?=} message
* @param {?=} title
* @param {?=} override
* @return {?}
*/
error(message, title, override = {}) {
/** @type {?} */
const type = this.toastrConfig.iconClasses.error || '';
return this._preBuildNotification(type, message, title, this.applyConfig(override));
}
/**
* show info toast
* @param {?=} message
* @param {?=} title
* @param {?=} override
* @return {?}
*/
info(message, title, override = {}) {
/** @type {?} */
const type = this.toastrConfig.iconClasses.info || '';
return this._preBuildNotification(type, message, title, this.applyConfig(override));
}
/**
* show warning toast
* @param {?=} message
* @param {?=} title
* @param {?=} override
* @return {?}
*/
warning(message, title, override = {}) {
/** @type {?} */
const type = this.toastrConfig.iconClasses.warning || '';
return this._preBuildNotification(type, message, title, this.applyConfig(override));
}
/**
* Remove all or a single toast by id
* @param {?=} toastId
* @return {?}
*/
clear(toastId) {
// Call every toastRef manualClose function
for (const toast of this.toasts) {
if (toastId !== undefined) {
if (toast.toastId === toastId) {
toast.toastRef.manualClose();
return;
}
}
else {
toast.toastRef.manualClose();
}
}
}
/**
* Remove and destroy a single toast by id
* @param {?} toastId
* @return {?}
*/
remove(toastId) {
/** @type {?} */
const found = this._findToast(toastId);
if (!found) {
return false;
}
found.activeToast.toastRef.close();
this.toasts.splice(found.index, 1);
this.currentlyActive = this.currentlyActive - 1;
if (!this.toastrConfig.maxOpened || !this.toasts.length) {
return false;
}
if (this.currentlyActive < this.toastrConfig.maxOpened &&
this.toasts[this.currentlyActive]) {
/** @type {?} */
const p = this.toasts[this.currentlyActive].toastRef;
if (!p.isInactive()) {
this.currentlyActive = this.currentlyActive + 1;
p.activate();
}
}
return true;
}
/**
* Finds a duplicate toast if one exists
* @param {?} message
* @param {?} resetOnDuplicate
* @return {?}
*/
findDuplicate(message, resetOnDuplicate) {
for (let i = 0; i < this.toasts.length; i++) {
/** @type {?} */
const toast = this.toasts[i];
if (toast.message === message) {
if (resetOnDuplicate && toast.toastRef.componentInstance.resetTimeout) {
toast.toastRef.resetTimeout();
}
return toast;
}
}
return null;
}
/**
* create a clone of global config and apply individual settings
* @param {?=} override
* @return {?}
*/
applyConfig(override = {}) {
return Object.assign({}, this.toastrConfig, override);
}
/**
* Find toast object by id
* @param {?} toastId
* @return {?}
*/
_findToast(toastId) {
for (let i = 0; i < this.toasts.length; i++) {
if (this.toasts[i].toastId === toastId) {
return { index: i, activeToast: this.toasts[i] };
}
}
return null;
}
/**
* Determines the need to run inside angular's zone then builds the toast
* @param {?} toastType
* @param {?} message
* @param {?} title
* @param {?} config
* @return {?}
*/
_preBuildNotification(toastType, message, title, config) {
if (config.onActivateTick) {
return this.ngZone.run(() => this._buildNotification(toastType, message, title, config));
}
return this._buildNotification(toastType, message, title, config);
}
/**
* Creates and attaches toast data to component
* returns the active toast, or in case preventDuplicates is enabled the original/non-duplicate active toast.
* @param {?} toastType
* @param {?} message
* @param {?} title
* @param {?} config
* @return {?}
*/
_buildNotification(toastType, message, title, config) {
if (!config.toastComponent) {
throw new Error('toastComponent required');
}
// max opened and auto dismiss = true
if (message &&
this.toastrConfig.preventDuplicates) {
/** @type {?} */
const duplicate = this.findDuplicate(message, this.toastrConfig.resetTimeoutOnDuplicate);
if (duplicate !== null) {
return duplicate;
}
}
this.previousToastMessage = message;
/** @type {?} */
let keepInactive = false;
if (this.toastrConfig.maxOpened &&
this.currentlyActive >= this.toastrConfig.maxOpened) {
keepInactive = true;
if (this.toastrConfig.autoDismiss) {
this.clear(this.toasts[0].toastId);
}
}
/** @type {?} */
const overlayRef = this.overlay.create(config.position, this.overlayContainer);
this.index = this.index + 1;
/** @type {?} */
let sanitizedMessage = message;
if (message && config.enableHtml) {
sanitizedMessage = this.sanitizer.sanitize(SecurityContext.HTML, message);
}
/** @type {?} */
const toastRef = new ToastrRef(overlayRef);
/** @type {?} */
const toastPackage = new ToastPackage(this.index, config, sanitizedMessage, title, toastType, toastRef);
/** @type {?} */
const toastInjector = new ToastrInjector(toastPackage, this._injector);
/** @type {?} */
const component = new ComponentPortal$1(config.toastComponent, toastInjector);
/** @type {?} */
const portal = overlayRef.attach(component, this.toastrConfig.newestOnTop);
toastRef.componentInstance = ((/** @type {?} */ (portal)))._component;
/** @type {?} */
const ins = {
toastId: this.index,
message: message || '',
toastRef,
onShown: toastRef.afterActivate(),
onHidden: toastRef.afterClosed(),
onTap: toastPackage.onTap(),
onAction: toastPackage.onAction(),
portal
};
if (!keepInactive) {
setTimeout(() => {
ins.toastRef.activate();
this.currentlyActive = this.currentlyActive + 1;
});
}
this.toasts.push(ins);
return ins;
}
}
ToastrService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] },
];
/** @nocollapse */
ToastrService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [TOAST_CONFIG,] }] },
{ type: Overlay$1 },
{ type: Injector },
{ type: DomSanitizer },
{ type: NgZone }
];
/** @nocollapse */ ToastrService.ngInjectableDef = defineInjectable({ factory: function ToastrService_Factory() { return new ToastrService(inject(TOAST_CONFIG), inject(Overlay$1), inject(INJECTOR), inject(DomSanitizer), inject(NgZone)); }, token: ToastrService, providedIn: "root" });
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class ToastrComponent {
/**
* @param {?} toastrService
* @param {?} toastPackage
* @param {?=} ngZone
*/
constructor(toastrService, toastPackage, ngZone) {
this.toastrService = toastrService;
this.toastPackage = toastPackage;
this.ngZone = ngZone;
/**
* width of progress bar
*/
this.width = -1;
/**
* a combination of toast type and options.toastClass
*/
this.toastClasses = '';
/**
* controls animation
*/
this.state = {
value: 'inactive',
params: {
easeTime: this.toastPackage.config.easeTime,
easing: 'ease-in'
}
};
this.message = toastPackage.message;
this.title = toastPackage.title;
this.options = toastPackage.config;
this.originalTimeout = toastPackage.config.timeOut;
this.toastClasses = `${toastPackage.toastType} ${toastPackage.config.toastClass}`;
this.sub = toastPackage.toastRef.afterActivate().subscribe(() => {
this.activateToast();
});
this.sub1 = toastPackage.toastRef.manualClosed().subscribe(() => {
this.remove();
});
this.sub2 = toastPackage.toastRef.timeoutReset().subscribe(() => {
this.resetTimeout();
});
}
/**
* @return {?}
*/
ngOnDestroy() {
this.sub.unsubscribe();
this.sub1.unsubscribe();
this.sub2.unsubscribe();
clearInterval(this.intervalId);
clearTimeout(this.timeout);
}
/**
* activates toast and sets timeout
* @return {?}
*/
activateToast() {
this.state = Object.assign({}, this.state, { value: 'active' });
if (!this.options.disableTimeOut && this.options.timeOut) {
this.outsideTimeout(() => this.remove(), this.options.timeOut);
this.hideTime = new Date().getTime() + this.options.timeOut;
if (this.options.progressBar) {
this.outsideInterval(() => this.updateProgress(), 10);
}
}
}
/**
* updates progress bar width
* @return {?}
*/
updateProgress() {
if (this.width === 0 || this.width === 100 || !this.options.timeOut) {
return;
}
/** @type {?} */
const now = new Date().getTime();
/** @type {?} */
const remaining = this.hideTime - now;
this.width = (remaining / this.options.timeOut) * 100;
if (this.options.progressAnimation === 'increasing') {
this.width = 100 - this.width;
}
if (this.width <= 0) {
this.width = 0;
}
if (this.width >= 100) {
this.width = 100;
}
}
/**
* @return {?}
*/
resetTimeout() {
clearTimeout(this.timeout);
clearInterval(this.intervalId);
this.state = Object.assign({}, this.state, { value: 'active' });
this.outsideTimeout(() => this.remove(), this.originalTimeout);
this.options.timeOut = this.originalTimeout;
this.hideTime = new Date().getTime() + (this.options.timeOut || 0);
this.width = -1;
if (this.options.progressBar) {
this.outsideInterval(() => this.updateProgress(), 10);
}
}
/**
* tells toastrService to remove this toast after animation time
* @return {?}
*/
remove() {
if (this.state.value === 'removed') {
return;
}
clearTimeout(this.timeout);
this.state = Object.assign({}, this.state, { value: 'removed' });
this.outsideTimeout(() => this.toastrService.remove(this.toastPackage.toastId), +this.toastPackage.config.easeTime);
}
/**
* @return {?}
*/
tapToast() {
if (this.state.value === 'removed') {
return;
}
this.toastPackage.triggerTap();
if (this.options.tapToDismiss) {
this.remove();
}
}
/**
* @return {?}
*/
stickAround() {
if (this.state.value === 'removed') {
return;
}
clearTimeout(this.timeout);
this.options.timeOut = 0;
this.hideTime = 0;
// disable progressBar
clearInterval(this.intervalId);
this.width = 0;
}
/**
* @return {?}
*/
delayedHideToast() {
if (this.options.disableTimeOut ||
this.options.extendedTimeOut === 0 ||
this.state.value === 'removed') {
return;
}
this.outsideTimeout(() => this.remove(), this.options.extendedTimeOut);
this.options.timeOut = this.options.extendedTimeOut;
this.hideTime = new Date().getTime() + (this.options.timeOut || 0);
this.width = -1;
if (this.options.progressBar) {
this.outsideInterval(() => this.updateProgress(), 10);
}
}
/**
* @param {?} func
* @param {?} timeout
* @return {?}
*/
outsideTimeout(func, timeout) {
if (this.ngZone) {
this.ngZone.runOutsideAngular(() => (this.timeout = setTimeout(() => this.runInsideAngular(func), timeout)));
}
else {
this.timeout = setTimeout(() => func(), timeout);
}
}
/**
* @param {?} func
* @param {?} timeout
* @return {?}
*/
outsideInterval(func, timeout) {
if (this.ngZone) {
this.ngZone.runOutsideAngular(() => (this.intervalId = setInterval(() => this.runInsideAngular(func), timeout)));
}
else {
this.intervalId = setInterval(() => func(), timeout);
}
}
/**
* @param {?} func
* @return {?}
*/
runInsideAngular(func) {
if (this.ngZone) {
this.ngZone.run(() => func());
}
else {
func();
}
}
}
ToastrComponent.decorators = [
{ type: Component, args: [{
selector: '[hxa-toastr-component]',
template: `
<span class="hx-icon-control mr-2">
<i class="hx-icon is-medium icon-information" *ngIf="toastPackage.toastType === 'is-info' || toastPackage.toastType === ''"></i>
<i class="hx-icon is-medium icon-check" *ngIf="toastPackage.toastType === 'is-success'"></i>
<i class="hx-icon is-medium icon-warning" *ngIf="toastPackage.toastType === 'is-warning' || toastPackage.toastType === 'is-danger'"></i>
</span>
<div class="hx-flex-1">
<div *ngIf="title" [class]="options.titleClass" [attr.aria-label]="title">
{{ title }}
</div>
<div *ngIf="message && options.enableHtml" role="alertdialog" aria-live="polite"
[class]="options.messageClass" [innerHTML]="message">
</div>
<div *ngIf="message && !options.enableHtml" role="alertdialog" aria-live="polite"
[class]="options.messageClass" [attr.aria-label]="message">
{{ message }}
</div>
</div>
<div *ngIf="options.progressBar">
<div class="toast-progress" [style.width]="width + '%'"></div>
</div>
<span *ngIf="options.closeButton" class="hx-icon-control ml-8">
<button (click)="remove()" aria-label="Close" class="hx-delete"> <span aria-hidden="true">×</span></button>
</span>
`,
animations: [
trigger('flyInOut', [
state('inactive', style({
display: 'none',
opacity: 0
})),
state('active', style({})),
state('removed', style({ opacity: 0 })),
transition('inactive => active', animate('{{ easeTime }}ms {{ easing }}')),
transition('active => removed', animate('{{ easeTime }}ms {{ easing }}'))
])
],
preserveWhitespaces: false
},] },
];
/** @nocollapse */
ToastrComponent.ctorParameters = () => [
{ type: ToastrService },
{ type: ToastPackage },
{ type: NgZone }
];
ToastrComponent.propDecorators = {
toastClasses: [{ type: HostBinding, args: ['class',] }],
state: [{ type: HostBinding, args: ['@flyInOut',] }],
tapToast: [{ type: HostListener, args: ['click',] }],
stickAround: [{ type: HostListener, args: ['mouseenter',] }],
delayedHideToast: [{ type: HostListener, args: ['mouseleave',] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @type {?} */
const DefaultGlobalConfig = Object.assign({}, DefaultNoComponentGlobalConfig, { toastComponent: ToastrComponent });
class ToastrModule {
/**
* @param {?=} config
* @return {?}
*/
static forRoot(config = {}) {
return {
ngModule: ToastrModule,
providers: [
{
provide: TOAST_CONFIG,
useValue: {
default: DefaultGlobalConfig,
config,
},
},
],
};
}
}
ToastrModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
declarations: [ToastrComponent],
exports: [ToastrComponent],
entryComponents: [ToastrComponent],
},] },
];
class ToastrComponentlessModule {
/**
* @param {?=} config
* @return {?}
*/
static forRoot(config = {}) {
return {
ngModule: ToastrModule,
providers: [
{
provide: TOAST_CONFIG,
useValue: {
default: DefaultNoComponentGlobalConfig,
config,
},
},
],
};
}
}
ToastrComponentlessModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class TextInputDirective {
/**
* @param {?} el
*/
constructor(el) {
this.el = el;
this.styleLabel();
}
/**
* @return {?}
*/
onFocus() {
this.styleLabelAsFloating();
}
/**
* @return {?}
*/
onBlur() {
this.styleLabel();
}
/**
* @return {?}
*/
styleLabel() {
// If the element is empty, style the label like a placeholder otherwise float the label above the input
if (this.el.nativeElement.value.trim().length === 0 && this.el.nativeElement.placeholder.trim().length === 0) {
this.styleLabelAsPlaceholder();
}
else {
this.styleLabelAsFloating();
}
}
/**
* @return {?}
*/
styleLabelAsPlaceholder() {
this.isPlaceholder = true;
this.isLabel = false;
}
/**
* @return {?}
*/
styleLabelAsFloating() {
this.isPlaceholder = false;
this.isLabel = true;
}
}
TextInputDirective.decorators = [
{ type: Directive, args: [{
selector: '[hxaTextInput]'
},] },
];
/** @nocollapse */
TextInputDirective.ctorParameters = () => [
{ type: ElementRef }
];
TextInputDirective.propDecorators = {
isPlaceholder: [{ type: HostBinding, args: ['class.has-label-placeholder',] }],
isLabel: [{ type: HostBinding, args: ['class.has-label-floating',] }],
onFocus: [{ type: HostListener, args: ['focus',] }],
onBlur: [{ type: HostListener, args: ['blur',] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class TextInputModule {
}
TextInputModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule
],
declarations: [
TextInputDirective
],
exports: [
TextInputDirective
]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @enum {number} */
const Context = {
None: 0,
Success: 1,
Warning: 2,
Danger: 3,
Info: 4,
};
Context[Context.None] = 'None';
Context[Context.Success] = 'Success';
Context[Context.Warning] = 'Warning';
Context[Context.Danger] = 'Danger';
Context[Context.Info] = 'Info';
/** @enum {number} */
const Size = {
Default: 0,
Small: 1,
Large: 2,
};
Size[Size.Default] = 'Default';
Size[Size.Small] = 'Small';
Size[Size.Large] = 'Large';
/** @enum {number} */
const Visibility = {
Hidden: 0,
Visible: 1,
};
Visibility[Visibility.Hidden] = 'Hidden';
Visibility[Visibility.Visible] = 'Visible';
/** @enum {string} */
const TextFieldTypes = {
Email: 'email',
Text: 'text',
Password: 'password',
Number: 'number',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class LoadersComponent {
constructor() {
this.size = Size.Default;
this.context = Context.None;
/**
* Enums to be used in the template *
*/
this.contextEnum = Context;
this.sizeEnum = Size;
}
/**
* @return {?}
*/
ngOnInit() {
}
}
LoadersComponent.decorators = [
{ type: Component, args: [{
selector: 'hxa-loader, hxa-loaders',
template: `<div class="hx-loader"
[class.is-small]="size === sizeEnum.Small"
[class.is-primary]="context === contextEnum.Success"
[class.is-warning]="context === contextEnum.Warning"
[class.is-danger]="context === contextEnum.Danger"
[class.is-info]="context === contextEnum.Info"><div></div><div></div><div></div><div></div></div>
`,
styles: [``]
},] },
];
/** @nocollapse */
LoadersComponent.ctorParameters = () => [];
LoadersComponent.propDecorators = {
size: [{ type: Input }],
context: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class LoadersModule {
}
LoadersModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule
],
declarations: [
LoadersComponent
],
exports: [
LoadersComponent
]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @enum {number} */
const FilterType = {
SingleSelect: 0,
Search: 1,
};
FilterType[FilterType.SingleSelect] = 'SingleSelect';
FilterType[FilterType.Search] = 'Search';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* Default dropdown configuration
*/
class DropdownConfig {
constructor() {
/**
* default dropdown auto closing behavior
*/
this.autoClose = true;
/**
* delay in ms before showing the dropdown after show is called
*/
this.showDelay = 0;
/**
* delay in ms before hiding the dropdown after hide is called
*/
this.hideDelay = 0;
}
}
DropdownConfig.decorators = [
{ type: Injectable },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class DropdownMenuDirective {
/**
* @param {?} _templateRef
*/
constructor(_templateRef) {
this.templateRef = _templateRef;
}
/**
* @return {?}
*/
ngOnInit() {
}
}
DropdownMenuDirective.decorators = [
{ type: Directive, args: [{
selector: '[hxDropdownMenu],[hxaDropdownMenu]',
exportAs: 'hx-dropdown-menu'
},] },
];
/** @nocollapse */
DropdownMenuDirective.ctorParameters = () => [
{ type: TemplateRef }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
class DropdownDirective {
/**
* @param {?} _elementRef
* @param {?} _viewContainerRef
* @param {?} overlay
* @param {?} _config
*/
constructor(_elementRef, _viewContainerRef, overlay, _config) {
this._elementRef = _elementRef;
this._viewContainerRef = _viewContainerRef;
this.overlay = overlay;
this._config = _config;
this._destroyed = new Subject$1();
this.isOpen = false;
this.placement = 'bottom';
this._autoClose = this._config.autoClose;
this.isOpenChange = new EventEmitter();
this.onShown = new EventEmitter();
this.onHidden = new EventEmitter();
this.isDisabled = false;