UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

602 lines 93.8 kB
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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