app/@overflow/commons/ui/component/primeng/popup-panel.component.ts

174 lines
3.9 KiB
TypeScript
Raw Normal View History

2018-08-18 01:04:59 +00:00
import { NgModule, Component, ElementRef, OnDestroy, Input, Renderer2, ViewChild, Inject, forwardRef } from '@angular/core';
import { trigger, state, style, transition, animate, AnimationEvent } from '@angular/animations';
import { DomHandler } from 'primeng/primeng';
@Component({
selector: 'of-p-popupPanel',
templateUrl: './popup-panel.component.html',
styleUrls: ['./popup-panel.component.scss'],
animations: [
trigger('overlayAnimation', [
state('void', style({
transform: 'translateY(5%)',
opacity: 0
})),
state('visible', style({
transform: 'translateY(0)',
opacity: 1
})),
transition('void => visible', animate('225ms ease-out')),
transition('visible => void', animate('195ms ease-in'))
])
],
providers: [DomHandler]
})
export class PopupPanelComponent implements OnDestroy {
@Input() blockTarget: any;
@Input() style: any;
@Input() styleClass: string;
@Input() appendTo: any;
@Input() autoZIndex = true;
@Input() baseZIndex = 0;
@ViewChild('container') containerViewChild: ElementRef;
private readonly popup = true;
container: HTMLDivElement;
documentClickListener: any;
documentResizeListener: any;
preventDocumentDefault: boolean;
target: any;
visible: boolean;
blockUIVisible = false;
constructor(public el: ElementRef, public domHandler: DomHandler, public renderer: Renderer2) { }
toggle(event) {
if (this.visible) {
this.hide();
} else {
this.show(event);
}
this.preventDocumentDefault = true;
}
show(event) {
this.target = event.currentTarget;
this.visible = true;
this.preventDocumentDefault = true;
}
onOverlayAnimationStart(event: AnimationEvent) {
switch (event.toState) {
case 'visible':
if (this.popup) {
this.container = event.element;
this.moveOnTop();
this.appendOverlay();
this.domHandler.absolutePosition(this.container, this.target);
this.bindDocumentClickListener();
this.bindDocumentResizeListener();
}
break;
case 'void':
this.onOverlayHide();
break;
}
}
onOverlayAnimationDone(event: AnimationEvent) {
console.log('onOverlayAnimationDone');
}
appendOverlay() {
if (this.appendTo) {
if (this.appendTo === 'body') {
document.body.appendChild(this.container);
} else {
this.domHandler.appendChild(this.container, this.appendTo);
}
}
}
restoreOverlayAppend() {
if (this.container && this.appendTo) {
this.el.nativeElement.appendChild(this.container);
}
}
moveOnTop() {
if (this.autoZIndex) {
this.container.style.zIndex = String(this.baseZIndex + (++DomHandler.zindex));
}
}
hide() {
this.visible = false;
}
onWindowResize() {
this.hide();
}
bindDocumentClickListener() {
if (!this.documentClickListener) {
this.documentClickListener = this.renderer.listen('document', 'click', () => {
if (!this.preventDocumentDefault) {
this.hide();
}
this.preventDocumentDefault = false;
});
}
}
unbindDocumentClickListener() {
if (this.documentClickListener) {
this.documentClickListener();
this.documentClickListener = null;
}
}
bindDocumentResizeListener() {
this.documentResizeListener = this.onWindowResize.bind(this);
window.addEventListener('resize', this.documentResizeListener);
}
unbindDocumentResizeListener() {
if (this.documentResizeListener) {
window.removeEventListener('resize', this.documentResizeListener);
this.documentResizeListener = null;
}
}
onOverlayHide() {
this.unbindDocumentClickListener();
this.unbindDocumentResizeListener();
this.preventDocumentDefault = false;
this.target = null;
}
ngOnDestroy() {
if (this.popup) {
this.restoreOverlayAppend();
this.onOverlayHide();
}
}
}