@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
602 lines • 93.8 kB
JavaScript
import { __decorate, __metadata, __param } from "tslib";
import { DOCUMENT } from '@angular/common';
import { GlobalPositionStrategy } from './position/global-position-strategy';
import { NoOpScrollStrategy } from './scroll/NoOpScrollStrategy';
import { ApplicationRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, ElementRef, EventEmitter, Inject, Injectable, Injector, Type, OnDestroy, NgModuleRef, NgZone } from '@angular/core';
import { AnimationBuilder, AnimationReferenceMetadata, AnimationMetadataType, AnimationAnimateRefMetadata } from '@angular/animations';
import { fromEvent, Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import { showMessage } from '../../core/deprecateDecorators';
import * as i0 from "@angular/core";
import * as i1 from "@angular/animations";
import * as i2 from "@angular/common";
let warningShown = false;
/**
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_main.html)
* The overlay service allows users to show components on overlay div above all other elements in the page.
*/
let IgxOverlayService = class IgxOverlayService {
constructor(_factoryResolver, _appRef, _injector, builder, document, _zone) {
this._factoryResolver = _factoryResolver;
this._appRef = _appRef;
this._injector = _injector;
this.builder = builder;
this.document = document;
this._zone = _zone;
this._componentId = 0;
this._overlayInfos = [];
this.destroy$ = new Subject();
this._defaultSettings = {
positionStrategy: new GlobalPositionStrategy(),
scrollStrategy: new NoOpScrollStrategy(),
modal: true,
closeOnOutsideClick: true
};
/**
* Emitted before the component is opened.
* ```typescript
* onOpening(event: OverlayCancelableEventArgs){
* const onOpening = event;
* }
* ```
*/
this.onOpening = new EventEmitter();
/**
* Emitted after the component is opened and all animations are finished.
* ```typescript
* onOpened(event: OverlayEventArgs){
* const onOpened = event;
* }
* ```
*/
this.onOpened = new EventEmitter();
/**
* Emitted before the component is closed.
* ```typescript
* onClosing(event: OverlayCancelableEventArgs){
* const onClosing = event;
* }
* ```
*/
this.onClosing = new EventEmitter();
/**
* Emitted after the component is closed and all animations are finished.
* ```typescript
* onClosed(event: OverlayEventArgs){
* const onClosed = event;
* }
* ```
*/
this.onClosed = new EventEmitter();
/**
* Emitted before animation is started
* ```typescript
* onAnimation(event: OverlayAnimationEventArgs){
* const onAnimation = event;
* }
* ```
*/
this.onAnimation = new EventEmitter();
this.documentClicked = (ev) => {
// if we get to modal overlay just return - we should not close anything under it
// if we get to non-modal overlay do the next:
// 1. Check it has close on outside click. If not go on to next overlay;
// 2. If true check if click is on the element. If it is on the element we have closed
// already all previous non-modal with close on outside click elements, so we return. If
// not close the overlay and check next
for (let i = this._overlayInfos.length; i--;) {
const info = this._overlayInfos[i];
if (info.settings.modal) {
return;
}
if (info.settings.closeOnOutsideClick) {
const target = ev.target;
// if the click is on the element do not close this overlay
if (!info.elementRef.nativeElement.contains(target)) {
// if we should exclude position target check if the click is over it. If so do not close overlay
const positionTarget = info.settings.positionStrategy.settings.target;
let clickOnPositionTarget = false;
if (positionTarget) {
clickOnPositionTarget = positionTarget.contains(target);
}
if (!(info.settings.excludePositionTarget && clickOnPositionTarget)) {
// if the click is outside click, but close animation has started do nothing
if (!(info.closeAnimationPlayer && info.closeAnimationPlayer.hasStarted())) {
this._hide(info.id, ev);
}
}
}
else {
// TODO: should we return here, or continue with next overlays
return;
}
}
}
};
/** @hidden */
this.repositionAll = () => {
for (let i = this._overlayInfos.length; i--;) {
this.reposition(this._overlayInfos[i].id);
}
};
this._document = this.document;
}
attach(component, settings, moduleRef) {
let info;
info = this.getOverlayInfo(component, moduleRef);
// if there is no info most probably wrong type component was provided and we just go out
if (!info) {
return null;
}
info.id = (this._componentId++).toString();
settings = Object.assign({}, this._defaultSettings, settings);
info.settings = settings;
this._overlayInfos.push(info);
return info.id;
}
show(compOrId, settings) {
let info;
let id;
if (typeof compOrId === 'string') {
id = compOrId;
info = this.getOverlayById(compOrId);
if (!info) {
console.warn('igxOverlay.show was called with wrong id: ' + compOrId);
return null;
}
}
else {
warningShown = showMessage('`show(component, settings?)` overload is deprecated. Use `attach(component)` to obtain an Id.' +
'Then `show(id, settings?)` with provided Id.', warningShown);
id = (this._componentId++).toString();
info = this.getOverlayInfo(compOrId);
// if there is no info most probably wrong type component was provided and we just go out
if (!info) {
return;
}
info.id = id;
}
settings = Object.assign({}, this._defaultSettings, info.settings, settings);
info.settings = settings;
this._show(info);
return id;
}
/**
* Hides the component with the ID provided as a parameter.
* ```typescript
* this.overlay.hide(id);
* ```
*/
hide(id) {
this._hide(id);
}
/**
* Hides all the components and the overlay.
* ```typescript
* this.overlay.hideAll();
* ```
*/
hideAll() {
// since overlays are removed on animation done, que all hides
for (let i = this._overlayInfos.length; i--;) {
this.hide(this._overlayInfos[i].id);
}
}
/**
* Repositions the component with ID provided as a parameter.
* ```typescript
* this.overlay.reposition(id);
* ```
*/
reposition(id) {
const overlayInfo = this.getOverlayById(id);
if (!overlayInfo || !overlayInfo.settings) {
console.error('Wrong id provided in overlay.reposition method. Id: ' + id);
return;
}
const contentElement = overlayInfo.elementRef.nativeElement.parentElement;
const contentElementRect = contentElement.getBoundingClientRect();
overlayInfo.settings.positionStrategy.position(contentElement, {
width: contentElementRect.width,
height: contentElementRect.height
}, this._document, false);
}
/**
* Offsets the content along the corresponding axis by the provided amount
* ```typescript
* this.overlay.setOffset(id, deltaX, deltaY);
* ```
*/
setOffset(id, deltaX, deltaY) {
const info = this.getOverlayById(id);
if (!info) {
return;
}
info.transformX += deltaX;
info.transformY += deltaY;
const transformX = info.transformX;
const transformY = info.transformY;
const translate = `translate(${transformX}px, ${transformY}px)`;
info.elementRef.nativeElement.parentElement.style.transform = translate;
}
_show(info) {
const eventArgs = { id: info.id, componentRef: info.componentRef, cancel: false };
this.onOpening.emit(eventArgs);
if (eventArgs.cancel) {
if (info.componentRef) {
this._appRef.detachView(info.componentRef.hostView);
info.componentRef.destroy();
}
return;
}
// if there is no close animation player, or there is one but it is not started yet we are in clear
// opening. Otherwise, if there is close animation player playing animation now we should not setup
// overlay this is already done
if (!info.closeAnimationPlayer || (info.closeAnimationPlayer && !info.closeAnimationPlayer.hasStarted())) {
const elementRect = info.elementRef.nativeElement.getBoundingClientRect();
info.initialSize = { width: elementRect.width, height: elementRect.height };
info.hook = this.placeElementHook(info.elementRef.nativeElement);
this.moveElementToOverlay(info);
if (info.componentRef) {
info.componentRef.changeDetectorRef.detectChanges();
}
this.updateSize(info);
if (this._overlayInfos.indexOf(info) === -1) {
this._overlayInfos.push(info);
}
info.settings.positionStrategy.position(info.elementRef.nativeElement.parentElement, { width: info.initialSize.width, height: info.initialSize.height }, document, true);
info.settings.scrollStrategy.initialize(this._document, this, info.id);
info.settings.scrollStrategy.attach();
}
this.addOutsideClickListener(info);
this.addResizeHandler(info.id);
if (info.settings.modal) {
this.setupModalWrapper(info);
}
if (info.settings.positionStrategy.settings.openAnimation) {
this.playOpenAnimation(info);
}
else {
// to eliminate flickering show the element just before onOpened fire
info.elementRef.nativeElement.parentElement.style.visibility = '';
this.onOpened.emit({ id: info.id, componentRef: info.componentRef });
}
}
_hide(id, event) {
const info = this.getOverlayById(id);
if (!info) {
console.warn('igxOverlay.hide was called with wrong id: ' + id);
return;
}
const eventArgs = { id, componentRef: info.componentRef, cancel: false, event };
this.onClosing.emit(eventArgs);
if (eventArgs.cancel) {
return;
}
// TODO: synchronize where these are added/attached and where removed/detached
info.settings.scrollStrategy.detach();
this.removeOutsideClickListener(info);
this.removeResizeHandler(info.id);
const child = info.elementRef.nativeElement;
if (info.settings.modal) {
const parent = child.parentNode.parentNode;
this.applyAnimationParams(parent, info.settings.positionStrategy.settings.closeAnimation);
parent.classList.remove('igx-overlay__wrapper--modal');
parent.classList.add('igx-overlay__wrapper');
}
if (info.settings.positionStrategy.settings.closeAnimation) {
this.playCloseAnimation(info);
}
else {
this.onCloseDone(info);
}
}
getOverlayInfo(component, moduleRef) {
const info = { ngZone: this._zone, transformX: 0, transformY: 0 };
if (component instanceof ElementRef) {
info.elementRef = component;
}
else {
let dynamicFactory;
const factoryResolver = moduleRef ? moduleRef.componentFactoryResolver : this._factoryResolver;
try {
dynamicFactory = factoryResolver.resolveComponentFactory(component);
}
catch (error) {
console.error(error);
return null;
}
const injector = moduleRef ? moduleRef.injector : this._injector;
const dynamicComponent = dynamicFactory.create(injector);
this._appRef.attachView(dynamicComponent.hostView);
// If the element is newly created from a Component, it is wrapped in 'ng-component' tag - we do not want that.
const element = dynamicComponent.location.nativeElement;
info.elementRef = { nativeElement: element };
info.componentRef = dynamicComponent;
}
return info;
}
placeElementHook(element) {
if (!element.parentElement) {
return null;
}
const hook = this._document.createElement('div');
element.parentElement.insertBefore(hook, element);
return hook;
}
moveElementToOverlay(info) {
const wrapperElement = this.getWrapperElement();
const contentElement = this.getContentElement(wrapperElement, info.settings.modal);
this.getOverlayElement(info).appendChild(wrapperElement);
const elementScrollTop = info.elementRef.nativeElement.scrollTop;
contentElement.appendChild(info.elementRef.nativeElement);
if (elementScrollTop) {
info.elementRef.nativeElement.scrollTop = elementScrollTop;
}
}
getWrapperElement() {
const wrapper = this._document.createElement('div');
wrapper.classList.add('igx-overlay__wrapper');
return wrapper;
}
getContentElement(wrapperElement, modal) {
const content = this._document.createElement('div');
if (modal) {
content.classList.add('igx-overlay__content--modal');
content.addEventListener('click', (ev) => {
ev.stopPropagation();
});
}
else {
content.classList.add('igx-overlay__content');
}
content.addEventListener('scroll', (ev) => {
ev.stopPropagation();
});
// hide element to eliminate flickering. Show the element exactly before animation starts
content.style.visibility = 'hidden';
wrapperElement.appendChild(content);
return content;
}
getOverlayElement(info) {
if (info.settings.outlet) {
return info.settings.outlet.nativeElement;
}
if (!this._overlayElement) {
this._overlayElement = this._document.createElement('div');
this._overlayElement.classList.add('igx-overlay');
this._document.body.appendChild(this._overlayElement);
}
return this._overlayElement;
}
updateSize(info) {
if (info.componentRef) {
// if we are positioning component this is first time it gets visible
// and we can finally get its size
info.initialSize = info.elementRef.nativeElement.getBoundingClientRect();
}
// set content div width only if element to show has width
if (info.initialSize.width !== 0) {
info.elementRef.nativeElement.parentElement.style.width = info.initialSize.width + 'px';
}
}
setupModalWrapper(info) {
const wrapperElement = info.elementRef.nativeElement.parentElement.parentElement;
fromEvent(wrapperElement, 'keydown').pipe(filter((ev) => ev.key === 'Escape' || ev.key === 'Esc'), takeUntil(this.destroy$)).subscribe(() => this.hide(info.id));
wrapperElement.classList.remove('igx-overlay__wrapper');
this.applyAnimationParams(wrapperElement, info.settings.positionStrategy.settings.openAnimation);
wrapperElement.classList.add('igx-overlay__wrapper--modal');
}
onCloseDone(info) {
this.cleanUp(info);
this.onClosed.emit({ id: info.id, componentRef: info.componentRef });
}
cleanUp(info) {
const child = info.elementRef.nativeElement;
const outlet = this.getOverlayElement(info);
if (!outlet.contains(child)) {
console.warn('Component with id:' + info.id + ' is already removed!');
return;
}
outlet.removeChild(child.parentNode.parentNode);
if (info.componentRef) {
this._appRef.detachView(info.componentRef.hostView);
info.componentRef.destroy();
}
if (info.hook) {
info.hook.parentElement.insertBefore(info.elementRef.nativeElement, info.hook);
info.hook.parentElement.removeChild(info.hook);
}
const index = this._overlayInfos.indexOf(info);
this._overlayInfos.splice(index, 1);
// this._overlayElement.parentElement check just for tests that manually delete the element
if (this._overlayInfos.length === 0 && this._overlayElement && this._overlayElement.parentElement) {
this._overlayElement.parentElement.removeChild(this._overlayElement);
this._overlayElement = null;
}
}
playOpenAnimation(info) {
if (!info.openAnimationPlayer) {
const animationBuilder = this.builder.build(info.settings.positionStrategy.settings.openAnimation);
info.openAnimationPlayer = animationBuilder.create(info.elementRef.nativeElement);
// AnimationPlayer.getPosition returns always 0. To workaround this we are getting inner WebAnimationPlayer
// and then getting the positions from it.
// This is logged in Angular here - https://github.com/angular/angular/issues/18891
// As soon as this is resolved we can remove this hack
const innerRenderer = info.openAnimationPlayer._renderer;
info.openAnimationInnerPlayer = innerRenderer.engine.players[innerRenderer.engine.players.length - 1];
info.openAnimationPlayer.onDone(() => {
this.onOpened.emit({ id: info.id, componentRef: info.componentRef });
if (info.openAnimationPlayer) {
info.openAnimationPlayer.reset();
info.openAnimationPlayer = null;
}
if (info.closeAnimationPlayer && info.closeAnimationPlayer.hasStarted()) {
info.closeAnimationPlayer.reset();
}
});
}
// if there is opening animation already started do nothing
if (info.openAnimationPlayer.hasStarted()) {
return;
}
// if there is closing animation already started start open animation from where close one has reached
// and remove close animation
if (info.closeAnimationPlayer && info.closeAnimationPlayer.hasStarted()) {
// getPosition() returns what part of the animation is passed, e.g. 0.5 if half the animation
// is done, 0.75 if 3/4 of the animation is done. As we need to start next animation from where
// the previous has finished we need the amount up to 1, therefore we are subtracting what
// getPosition() returns from one
const position = 1 - info.closeAnimationInnerPlayer.getPosition();
info.closeAnimationPlayer.reset();
info.closeAnimationPlayer = null;
info.openAnimationPlayer.init();
info.openAnimationPlayer.setPosition(position);
}
this.onAnimation.emit({ id: info.id, animationPlayer: info.openAnimationPlayer, animationType: 'open' });
// to eliminate flickering show the element just before animation start
info.elementRef.nativeElement.parentElement.style.visibility = '';
info.openAnimationPlayer.play();
}
playCloseAnimation(info) {
if (!info.closeAnimationPlayer) {
const animationBuilder = this.builder.build(info.settings.positionStrategy.settings.closeAnimation);
info.closeAnimationPlayer = animationBuilder.create(info.elementRef.nativeElement);
// AnimationPlayer.getPosition returns always 0. To workaround this we are getting inner WebAnimationPlayer
// and then getting the positions from it.
// This is logged in Angular here - https://github.com/angular/angular/issues/18891
// As soon as this is resolved we can remove this hack
const innerRenderer = info.closeAnimationPlayer._renderer;
info.closeAnimationInnerPlayer = innerRenderer.engine.players[innerRenderer.engine.players.length - 1];
info.closeAnimationPlayer.onDone(() => {
if (info.closeAnimationPlayer) {
info.closeAnimationPlayer.reset();
info.closeAnimationPlayer = null;
}
if (info.openAnimationPlayer && info.openAnimationPlayer.hasStarted()) {
info.openAnimationPlayer.reset();
}
this.onCloseDone(info);
});
}
// if there is closing animation already started do nothing
if (info.closeAnimationPlayer.hasStarted()) {
return;
}
// if there is opening animation already started start close animation from where open one has reached
// and remove open animation
if (info.openAnimationPlayer && info.openAnimationPlayer.hasStarted()) {
// getPosition() returns what part of the animation is passed, e.g. 0.5 if half the animation
// is done, 0.75 if 3/4 of the animation is done. As we need to start next animation from where
// the previous has finished we need the amount up to 1, therefore we are subtracting what
// getPosition() returns from one
const position = 1 - info.openAnimationInnerPlayer.getPosition();
info.openAnimationPlayer.reset();
info.openAnimationPlayer = null;
info.closeAnimationPlayer.init();
info.closeAnimationPlayer.setPosition(position);
}
this.onAnimation.emit({ id: info.id, animationPlayer: info.closeAnimationPlayer, animationType: 'close' });
info.closeAnimationPlayer.play();
}
// TODO: check if applyAnimationParams will work with complex animations
applyAnimationParams(wrapperElement, animationOptions) {
if (!animationOptions) {
wrapperElement.style.transitionDuration = '0ms';
return;
}
if (animationOptions.type === 10 /* AnimateRef */) {
animationOptions = animationOptions.animation;
}
if (!animationOptions.options || !animationOptions.options.params) {
return;
}
const params = animationOptions.options.params;
if (params.duration) {
wrapperElement.style.transitionDuration = params.duration;
}
if (params.easing) {
wrapperElement.style.transitionTimingFunction = params.easing;
}
}
/** @hidden @internal */
getOverlayById(id) {
if (!id) {
return null;
}
const info = this._overlayInfos.find(e => e.id === id);
return info;
}
addOutsideClickListener(info) {
if (info.settings.closeOnOutsideClick) {
if (info.settings.modal) {
fromEvent(info.elementRef.nativeElement.parentElement.parentElement, 'click')
.pipe(takeUntil(this.destroy$))
.subscribe((e) => this._hide(info.id, e));
}
else if (
// if all overlays minus closing overlays equals one add the handler
this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal).length -
this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal &&
x.closeAnimationPlayer &&
x.closeAnimationPlayer.hasStarted()).length === 1) {
this._document.addEventListener('click', this.documentClicked, true);
}
}
}
removeOutsideClickListener(info) {
if (info.settings.modal === false) {
let shouldRemoveClickEventListener = true;
this._overlayInfos.forEach(o => {
if (o.settings.modal === false && o.id !== info.id) {
shouldRemoveClickEventListener = false;
}
});
if (shouldRemoveClickEventListener) {
this._document.removeEventListener('click', this.documentClicked, true);
}
}
}
addResizeHandler(id) {
const closingOverlaysCount = this._overlayInfos
.filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted())
.length;
if (this._overlayInfos.length - closingOverlaysCount === 1) {
this._document.defaultView.addEventListener('resize', this.repositionAll);
}
}
removeResizeHandler(id) {
const closingOverlaysCount = this._overlayInfos
.filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted())
.length;
if (this._overlayInfos.length - closingOverlaysCount === 1) {
this._document.defaultView.removeEventListener('resize', this.repositionAll);
}
}
/**
*@hidden
*/
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();
}
};
IgxOverlayService.ctorParameters = () => [
{ type: ComponentFactoryResolver },
{ type: ApplicationRef },
{ type: Injector },
{ type: AnimationBuilder },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: NgZone }
];
IgxOverlayService.ɵprov = i0.ɵɵdefineInjectable({ factory: function IgxOverlayService_Factory() { return new IgxOverlayService(i0.ɵɵinject(i0.ComponentFactoryResolver), i0.ɵɵinject(i0.ApplicationRef), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(i1.AnimationBuilder), i0.ɵɵinject(i2.DOCUMENT), i0.ɵɵinject(i0.NgZone)); }, token: IgxOverlayService, providedIn: "root" });
IgxOverlayService = __decorate([
Injectable({ providedIn: 'root' }),
__param(4, Inject(DOCUMENT)),
__metadata("design:paramtypes", [ComponentFactoryResolver,
ApplicationRef,
Injector,
AnimationBuilder, Object, NgZone])
], IgxOverlayService);
export { IgxOverlayService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvc2VydmljZXMvb3ZlcmxheS9vdmVybGF5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFVakUsT0FBTyxFQUNILGNBQWMsRUFDZCxnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixVQUFVLEVBQ1YsUUFBUSxFQUNSLElBQUksRUFDSixTQUFTLEVBQ1QsV0FBVyxFQUNYLE1BQU0sRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsMEJBQTBCLEVBQUUscUJBQXFCLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2SSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQzs7OztBQUU3RCxJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7QUFFekI7OztHQUdHO0FBRUgsSUFBYSxpQkFBaUIsR0FBOUIsTUFBYSxpQkFBaUI7SUFnRTFCLFlBQ1ksZ0JBQTBDLEVBQzFDLE9BQXVCLEVBQ3ZCLFNBQW1CLEVBQ25CLE9BQXlCLEVBQ1AsUUFBYSxFQUMvQixLQUFhO1FBTGIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUEwQjtRQUMxQyxZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUN2QixjQUFTLEdBQVQs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