/*- * ============LICENSE_START======================================================= * SDC * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= */ import { Directive, HostListener, ComponentRef, ViewContainerRef, ComponentFactoryResolver, ComponentFactory, Input, OnChanges, SimpleChange, Output, EventEmitter } from "@angular/core"; import {PopoverContentComponent} from "./popover-content.component"; @Directive({ selector: "[popover]", exportAs: "popover" }) export class PopoverComponent implements OnChanges { protected PopoverComponent = PopoverContentComponent; protected popover: ComponentRef; protected visible: boolean; constructor(protected viewContainerRef: ViewContainerRef, protected resolver: ComponentFactoryResolver) { } @Input("popover") content: string|PopoverContentComponent; @Input() popoverDisabled: boolean; @Input() popoverAnimation: boolean; @Input() popoverPlacement: "top"|"bottom"|"left"|"right"|"auto"|"auto top"|"auto bottom"|"auto left"|"auto right"; @Input() popoverTitle: string; @Input() popoverOnHover: boolean = false; @Input() popoverCloseOnClickOutside: boolean; @Input() popoverCloseOnMouseOutside: boolean; @Input() popoverDismissTimeout: number = 0; @Output() onShown = new EventEmitter(); @Output() onHidden = new EventEmitter(); @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; if (!this.popoverOnHover) return; if (this.popoverDisabled) return; this.hide(); } ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { if (changes["popoverDisabled"]) { if (changes["popoverDisabled"].currentValue) { this.hide(); } } } 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(this.PopoverComponent); if (!this.visible) return; this.popover = this.viewContainerRef.createComponent(factory); const popover = this.popover.instance as PopoverContentComponent; 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.onCloseFromOutside.subscribe(() => this.hide()); if (this.popoverDismissTimeout > 0) setTimeout(() => this.hide(), this.popoverDismissTimeout); } else { const popover = this.content as PopoverContentComponent; 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 (this.popoverDismissTimeout > 0) setTimeout(() => this.hide(), this.popoverDismissTimeout); popover.show(); } this.onShown.emit(this); } hide() { if (!this.visible) return; this.visible = false; if (this.popover) this.popover.destroy(); if (this.content instanceof PopoverContentComponent) (this.content as PopoverContentComponent).hideFromPopover(); this.onHidden.emit(this); } getElement() { return this.viewContainerRef.element.nativeElement; } }