UNPKG

ng2-encrm-components

Version:
184 lines (150 loc) 5.42 kB
import { Directive, HostListener, ComponentRef, ViewContainerRef, ComponentFactoryResolver, ComponentFactory, Input, OnChanges, SimpleChange } from "@angular/core"; import { PopoverContent } from "./popover-content.component"; @Directive({ selector: "[popover]", exportAs: "popover" }) export class Popover implements OnChanges { // ------------------------------------------------------------------------- // Properties // ------------------------------------------------------------------------- private popover: ComponentRef<PopoverContent>; private visible: boolean; // ------------------------------------------------------------------------- // Inputs / Outputs // ------------------------------------------------------------------------- @Input("popover") content: string|PopoverContent; @Input() popoverDisabled: boolean; @Input() popoverAnimation: boolean; @Input() popoverPlacement: "top"|"bottom"|"left"|"right"; @Input() popoverTitle: string; @Input() popoverOnHover: boolean = false; @Input() popoverCloseOnClickOutside: boolean; @Input() popoverCloseOnMouseOutside: boolean; @Input() popoverDismissTimeout: number = 0; @Input() flavor: 'default' | 'success' | 'danger' | 'warning' | 'info' = 'default'; // ------------------------------------------------------------------------- // Constructor // ------------------------------------------------------------------------- constructor(private viewContainerRef: ViewContainerRef, private resolver: ComponentFactoryResolver) { } // ------------------------------------------------------------------------- // Event listeners // ------------------------------------------------------------------------- @HostListener("click") showOrHideOnClick(): void { if (this.popoverOnHover) return; if (this.popoverDisabled) return; this.toggle(); } @HostListener("focusin") @HostListener("mouseenter") showOnHover(): void { if (!this.popoverOnHover) return; if (this.popoverDisabled) return; this.show(); } @HostListener("focusout") @HostListener("mouseleave") hideOnHover(): void { if (this.popoverCloseOnMouseOutside) return; // don't do anything since not we control this if (!this.popoverOnHover) return; if (this.popoverDisabled) return; this.hide(); } ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { if (changes['popoverDisabled']) { if (changes['popoverDisabled'].currentValue) { this.hide(); } } } // ------------------------------------------------------------------------- // Public Methods // ------------------------------------------------------------------------- toggle() { if (!this.visible) { this.show(); } else { this.hide(); } } show() { if (this.visible) return; this.visible = true; if (typeof this.content === "string") { const factory = this.resolver.resolveComponentFactory(PopoverContent); if (!this.visible) return; this.popover = this.viewContainerRef.createComponent(factory); const popover = this.popover.instance as PopoverContent; popover.popover = this; popover.content = this.content as string; if (this.popoverPlacement !== undefined) popover.placement = this.popoverPlacement; if (this.popoverAnimation !== undefined) popover.animation = this.popoverAnimation; if (this.popoverTitle !== undefined) popover.title = this.popoverTitle; if (this.popoverCloseOnClickOutside !== undefined) popover.closeOnClickOutside = this.popoverCloseOnClickOutside; if (this.popoverCloseOnMouseOutside !== undefined) popover.closeOnMouseOutside = this.popoverCloseOnMouseOutside; popover.flavor = this.flavor; popover.onCloseFromOutside.subscribe(() => this.hide()); // if dismissTimeout option is set, then this popover will be dismissed in dismissTimeout time if (this.popoverDismissTimeout > 0) setTimeout(() => this.hide(), this.popoverDismissTimeout); } else { const popover = this.content as PopoverContent; popover.popover = this; if (this.popoverPlacement !== undefined) popover.placement = this.popoverPlacement; if (this.popoverAnimation !== undefined) popover.animation = this.popoverAnimation; if (this.popoverTitle !== undefined) popover.title = this.popoverTitle; if (this.popoverCloseOnClickOutside !== undefined) popover.closeOnClickOutside = this.popoverCloseOnClickOutside; if (this.popoverCloseOnMouseOutside !== undefined) popover.closeOnMouseOutside = this.popoverCloseOnMouseOutside; popover.onCloseFromOutside.subscribe(() => this.hide()); // if dismissTimeout option is set, then this popover will be dismissed in dismissTimeout time if (this.popoverDismissTimeout > 0) setTimeout(() => this.hide(), this.popoverDismissTimeout); popover.show(); } } hide() { if (!this.visible) return; this.visible = false; if (this.popover) this.popover.destroy(); if (this.content instanceof PopoverContent) (this.content as PopoverContent).hideFromPopover(); } getElement() { return this.viewContainerRef.element.nativeElement; } }