ngx-smart-popover
Version:
Simple popover control for your angular (v4+) applications using bootstrap4 with smart reflection logic when overflowing the viewport. This is a continuation of ngx-popover (https://github.com/pleerock/ngx-popover). If you want to use it without bootstrap
1,262 lines (1,254 loc) • 48.2 kB
JavaScript
import { Component, ElementRef, ChangeDetectorRef, Renderer2, Input, ViewChild, HostListener, EventEmitter, Directive, ViewContainerRef, ComponentFactoryResolver, ApplicationRef, Injector, Output, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* Generated from: lib/popover.placement.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var PopoverPlacement = /** @class */ (function () {
function PopoverPlacement() {
}
PopoverPlacement.Bottom = 'bottom';
PopoverPlacement.BottomLeft = 'bottom-left';
PopoverPlacement.BottomRight = 'bottom-right';
PopoverPlacement.Left = 'left';
PopoverPlacement.Right = 'right';
PopoverPlacement.Top = 'top';
PopoverPlacement.TopLeft = 'top-left';
PopoverPlacement.TopRight = 'top-right';
return PopoverPlacement;
}());
/**
* @fileoverview added by tsickle
* Generated from: lib/popover-content.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var PopoverContentComponent = /** @class */ (function () {
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
function PopoverContentComponent(element, cdr, renderer) {
var _this = this;
this.element = element;
this.cdr = cdr;
this.renderer = renderer;
this.placement = PopoverPlacement.Top;
this.animation = true;
this.closeOnClickOutside = false;
this.closeOnMouseOutside = false;
this.appendToBody = false;
this.size = 'small';
this.onCloseFromOutside = new EventEmitter();
this.top = -10000;
this.left = -10000;
this.isIn = false;
this.opacity = 0;
this.transitionEnabled = false;
this.windowWidth = window.innerWidth;
this.windowHeight = window.innerHeight;
// -------------------------------------------------------------------------
// Anonymous
// -------------------------------------------------------------------------
/**
* Closes dropdown if user clicks outside of this directive.
*/
this.onDocumentMouseDown = (/**
* @param {?} event
* @return {?}
*/
function (event) {
/** @type {?} */
var element = _this.element.nativeElement;
if (!element || !_this.popover) {
return;
}
if (element.contains(event.target) || _this.popover.getElement().contains(event.target)) {
return;
}
_this.onCloseFromOutside.emit(undefined);
});
}
// -------------------------------------------------------------------------
// Lifecycle callbacks
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Lifecycle callbacks
// -------------------------------------------------------------------------
/**
* @return {?}
*/
PopoverContentComponent.prototype.ngAfterViewInit =
// -------------------------------------------------------------------------
// Lifecycle callbacks
// -------------------------------------------------------------------------
/**
* @return {?}
*/
function () {
var _this = this;
if (this.closeOnClickOutside) {
this.listenClickFunc = this.renderer.listen('document', 'mousedown', (/**
* @param {?} event
* @return {?}
*/
function (event) { return _this.onDocumentMouseDown(event); }));
}
if (this.closeOnMouseOutside) {
this.listenMouseFunc = this.renderer.listen('document', 'mouseover', (/**
* @param {?} event
* @return {?}
*/
function (event) { return _this.onDocumentMouseDown(event); }));
}
// Always close on mobile touch event outside.
this.listenTouchFunc = this.renderer.listen('document', 'touchstart', (/**
* @param {?} event
* @return {?}
*/
function (event) { return _this.onDocumentMouseDown(event); }));
this.show();
this.cdr.detectChanges();
};
/**
* @return {?}
*/
PopoverContentComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
if (this.closeOnClickOutside && this.listenClickFunc) {
this.listenClickFunc();
}
if (this.closeOnMouseOutside && this.listenMouseFunc) {
this.listenMouseFunc();
}
if (!!this.listenTouchFunc) {
this.listenTouchFunc();
}
};
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* @param {?} event
* @return {?}
*/
PopoverContentComponent.prototype.onResize =
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* @param {?} event
* @return {?}
*/
function (event) {
this.windowWidth = window.innerWidth;
this.windowHeight = window.innerHeight;
};
/**
* @return {?}
*/
PopoverContentComponent.prototype.updatePosition = /**
* @return {?}
*/
function () {
// if visible, reposition
if (this.opacity) {
/** @type {?} */
var p = this.positionElements(this.popover.getElement(), this.popoverDiv.nativeElement, this.placement);
this.top = p.top;
this.left = p.left;
}
};
/**
* @return {?}
*/
PopoverContentComponent.prototype.show = /**
* @return {?}
*/
function () {
if (!this.popover || !this.popover.getElement()) {
return;
}
/** @type {?} */
var p = this.positionElements(this.popover.getElement(), this.popoverDiv.nativeElement, this.placement);
this.top = p.top;
this.left = p.left;
this.isIn = true;
this.transitionEnabled = true;
this.opacity = 1;
};
/**
* @return {?}
*/
PopoverContentComponent.prototype.hide = /**
* @return {?}
*/
function () {
this.top = -10000;
this.left = -10000;
this.isIn = true;
this.popover.hide();
};
/**
* @return {?}
*/
PopoverContentComponent.prototype.hideFromPopover = /**
* @return {?}
*/
function () {
this.top = -10000;
this.left = -10000;
this.isIn = true;
this.transitionEnabled = false;
this.opacity = 0;
};
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
/**
* @protected
* @param {?} hostEl
* @param {?} targetEl
* @param {?} positionStr
* @param {?=} appendToBody
* @return {?}
*/
PopoverContentComponent.prototype.positionElements =
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
/**
* @protected
* @param {?} hostEl
* @param {?} targetEl
* @param {?} positionStr
* @param {?=} appendToBody
* @return {?}
*/
function (hostEl, targetEl, positionStr, appendToBody) {
if (appendToBody === void 0) { appendToBody = false; }
/** @type {?} */
var positionStrParts = ((/** @type {?} */ (positionStr))).split(' ');
/** @type {?} */
var pos0 = positionStrParts[0];
/** @type {?} */
var pos1 = positionStrParts[1] || 'center';
/** @type {?} */
var hostElPos = this.appendToBody || appendToBody ? this.offset(hostEl) : this.position(hostEl);
/** @type {?} */
var targetElWidth = targetEl.offsetWidth;
/** @type {?} */
var targetElHeight = targetEl.offsetHeight;
this.effectivePlacement = pos0 = this.getEffectivePlacement(pos0, hostEl, targetEl);
/** @type {?} */
var shiftWidth = {
center: (/**
* @return {?}
*/
function () {
return hostElPos.left + hostElPos.width / 2 - targetElWidth / 2;
}),
left: (/**
* @return {?}
*/
function () {
return hostElPos.left;
}),
right: (/**
* @return {?}
*/
function () {
return hostElPos.left + hostElPos.width;
}),
topOrBottomRight: (/**
* @return {?}
*/
function () {
return hostElPos.left + hostElPos.width / 2;
}),
topOrBottomLeft: (/**
* @return {?}
*/
function () {
return hostElPos.left - targetElWidth + hostElPos.width / 2;
})
};
/** @type {?} */
var shiftHeight = {
center: (/**
* @return {?}
*/
function () {
return hostElPos.top + hostElPos.height / 2 - targetElHeight / 2;
}),
top: (/**
* @return {?}
*/
function () {
return hostElPos.top;
}),
bottom: (/**
* @return {?}
*/
function () {
return hostElPos.top + hostElPos.height;
})
};
/** @type {?} */
var targetElPos;
switch (pos0) {
case PopoverPlacement.Right:
targetElPos = {
top: shiftHeight[pos1](),
left: shiftWidth[pos0]()
};
break;
case PopoverPlacement.Left:
targetElPos = {
top: shiftHeight[pos1](),
left: hostElPos.left - targetElWidth
};
break;
case PopoverPlacement.Bottom:
targetElPos = {
top: shiftHeight[pos0](),
left: shiftWidth[pos1]()
};
break;
case PopoverPlacement.TopLeft:
targetElPos = {
top: hostElPos.top - targetElHeight,
left: shiftWidth['topOrBottomLeft']()
};
break;
case PopoverPlacement.TopRight:
targetElPos = {
top: hostElPos.top - targetElHeight,
left: shiftWidth['topOrBottomRight']()
};
break;
case PopoverPlacement.BottomLeft:
targetElPos = {
top: shiftHeight[PopoverPlacement.Bottom](),
left: shiftWidth['topOrBottomLeft']()
};
break;
case PopoverPlacement.BottomRight:
targetElPos = {
top: shiftHeight[PopoverPlacement.Bottom](),
left: shiftWidth['topOrBottomRight']()
};
break;
default:
targetElPos = {
top: hostElPos.top - targetElHeight,
left: shiftWidth[pos1]()
};
break;
}
return targetElPos;
};
/**
* @protected
* @param {?} nativeEl
* @return {?}
*/
PopoverContentComponent.prototype.position = /**
* @protected
* @param {?} nativeEl
* @return {?}
*/
function (nativeEl) {
/** @type {?} */
var offsetParentBCR = { top: 0, left: 0 };
/** @type {?} */
var elBCR = this.offset(nativeEl);
/** @type {?} */
var offsetParentEl = this.parentOffsetEl(nativeEl);
if (offsetParentEl !== window.document) {
offsetParentBCR = this.offset(offsetParentEl);
offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
}
/** @type {?} */
var boundingClientRect = nativeEl.getBoundingClientRect();
return {
width: boundingClientRect.width || nativeEl.offsetWidth,
height: boundingClientRect.height || nativeEl.offsetHeight,
top: elBCR.top - offsetParentBCR.top,
left: elBCR.left - offsetParentBCR.left
};
};
/**
* @protected
* @param {?} nativeEl
* @return {?}
*/
PopoverContentComponent.prototype.offset = /**
* @protected
* @param {?} nativeEl
* @return {?}
*/
function (nativeEl) {
/** @type {?} */
var boundingClientRect = nativeEl.getBoundingClientRect();
return {
width: boundingClientRect.width || nativeEl.offsetWidth,
height: boundingClientRect.height || nativeEl.offsetHeight,
top: boundingClientRect.top + (window.pageYOffset || window.document.documentElement.scrollTop),
left: boundingClientRect.left + (window.pageXOffset || window.document.documentElement.scrollLeft)
};
};
/**
* @protected
* @param {?} nativeEl
* @param {?} cssProp
* @return {?}
*/
PopoverContentComponent.prototype.getStyle = /**
* @protected
* @param {?} nativeEl
* @param {?} cssProp
* @return {?}
*/
function (nativeEl, cssProp) {
if (((/** @type {?} */ (nativeEl))).currentStyle) { // IE
return ((/** @type {?} */ (nativeEl))).currentStyle[cssProp];
}
if (window.getComputedStyle) {
return ((/** @type {?} */ (window.getComputedStyle)))(nativeEl)[cssProp];
}
// finally try and get inline style
return ((/** @type {?} */ (nativeEl.style)))[cssProp];
};
/**
* @protected
* @param {?} nativeEl
* @return {?}
*/
PopoverContentComponent.prototype.isStaticPositioned = /**
* @protected
* @param {?} nativeEl
* @return {?}
*/
function (nativeEl) {
return (this.getStyle(nativeEl, 'position') || 'static') === 'static';
};
/**
* @protected
* @param {?} nativeEl
* @return {?}
*/
PopoverContentComponent.prototype.parentOffsetEl = /**
* @protected
* @param {?} nativeEl
* @return {?}
*/
function (nativeEl) {
/** @type {?} */
var offsetParent = nativeEl.offsetParent || window.document;
while (offsetParent && offsetParent !== window.document && this.isStaticPositioned(offsetParent)) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent || window.document;
};
// Check for overflow of the viewport and reflect the position if necessary.
// Check for overflow of the viewport and reflect the position if necessary.
/**
* @protected
* @param {?} placement
* @param {?} hostElement
* @param {?} targetElement
* @return {?}
*/
PopoverContentComponent.prototype.getEffectivePlacement =
// Check for overflow of the viewport and reflect the position if necessary.
/**
* @protected
* @param {?} placement
* @param {?} hostElement
* @param {?} targetElement
* @return {?}
*/
function (placement, hostElement, targetElement) {
/** @type {?} */
var hostElBoundingRect = hostElement.getBoundingClientRect();
/** @type {?} */
var desiredPlacement = placement || PopoverPlacement.Top;
// Determines if a popover overflows in a direction when in a specific position.
/** @type {?} */
var overflows = {
positionTop: {
top: hostElBoundingRect.top - targetElement.offsetHeight < 0,
right: hostElBoundingRect.left + hostElBoundingRect.width / 2 + targetElement.offsetWidth / 2 > this.windowWidth,
left: hostElBoundingRect.left + hostElBoundingRect.width / 2 - targetElement.offsetWidth / 2 < 0
},
positionTopRight: {
top: hostElBoundingRect.top - targetElement.offsetHeight < 0,
right: hostElBoundingRect.right + targetElement.offsetWidth > this.windowWidth
},
positionRight: {
top: hostElBoundingRect.top + hostElBoundingRect.height / 2 - targetElement.offsetHeight / 2 < 0,
right: hostElBoundingRect.right + targetElement.offsetWidth > this.windowWidth,
bottom: hostElBoundingRect.top + hostElBoundingRect.height / 2 + targetElement.offsetHeight / 2 > this.windowHeight
},
positionBottomRight: {
right: hostElBoundingRect.right + targetElement.offsetWidth > this.windowWidth,
bottom: hostElBoundingRect.bottom + targetElement.offsetHeight > this.windowHeight
},
positionBottom: {
right: hostElBoundingRect.left + hostElBoundingRect.width / 2 + targetElement.offsetWidth / 2 > this.windowWidth,
bottom: hostElBoundingRect.bottom + targetElement.offsetHeight > this.windowHeight,
left: hostElBoundingRect.left + hostElBoundingRect.width / 2 - targetElement.offsetWidth / 2 < 0
},
positionBottomLeft: {
bottom: hostElBoundingRect.bottom + targetElement.offsetHeight > this.windowHeight,
left: hostElBoundingRect.left - targetElement.offsetWidth < 0
},
positionLeft: {
left: hostElBoundingRect.left < targetElement.offsetWidth,
top: hostElBoundingRect.top + hostElBoundingRect.height / 2 - targetElement.offsetHeight / 2 < 0,
bottom: hostElBoundingRect.top + hostElBoundingRect.height / 2 + targetElement.offsetHeight / 2 > this.windowHeight
},
positionTopLeft: {
top: hostElBoundingRect.top - targetElement.offsetHeight < 0,
left: hostElBoundingRect.left - targetElement.offsetWidth < 0
}
};
if (desiredPlacement === PopoverPlacement.Top) {
// If it overflows on the top AND left, go to bottom-right.
if (overflows.positionTop.top && overflows.positionTop.left) {
return PopoverPlacement.BottomRight;
// If it overflows on the top AND right, go to bottom-left.
}
else if (overflows.positionTop.top && overflows.positionTop.right) {
return PopoverPlacement.BottomLeft;
// If it only overflows on the top, go to bottom.
}
else if (overflows.positionTop.top) {
return PopoverPlacement.Bottom;
// If it only overflows to the right, go to top-left.
}
else if (overflows.positionTop.right) {
return PopoverPlacement.TopLeft;
// If it only overflows to the left, go to top-right.
}
else if (overflows.positionTop.left) {
return PopoverPlacement.TopRight;
}
else {
return PopoverPlacement.Top;
}
}
if (desiredPlacement === PopoverPlacement.TopRight) {
// If it overflows on the top AND the right, try in the order: bottom, Bottom-left, left.
if (overflows.positionTopRight.top && overflows.positionTopRight.right) {
if (overflows.positionBottom.bottom) {
return PopoverPlacement.Left;
}
else if (overflows.positionBottom.right) {
return PopoverPlacement.BottomLeft;
}
else {
return PopoverPlacement.Bottom;
}
// If it only overflows on the top, try in the order: right, bottom-right.
}
else if (overflows.positionTopRight.top) {
if (overflows.positionRight.top) {
return PopoverPlacement.BottomRight;
}
else {
return PopoverPlacement.Right;
}
// If it only overflows on the right, try in the order: top, top-left.
}
else if (overflows.positionTopRight.right) {
if (overflows.positionTop.right) {
return PopoverPlacement.TopLeft;
}
else {
return PopoverPlacement.Top;
}
}
else {
return PopoverPlacement.TopRight;
}
}
if (desiredPlacement === PopoverPlacement.Right) {
// If it overflows on the right AND the top, try in the order: bottom-right, bottom, bottom-left.
if (overflows.positionRight.right && overflows.positionRight.top) {
if (overflows.positionBottomRight.right && overflows.positionBottom.right) {
return PopoverPlacement.BottomLeft;
}
else if (overflows.positionBottomRight.right) {
return PopoverPlacement.Bottom;
}
else {
return PopoverPlacement.BottomRight;
}
// If it overflows on the right AND the bottom, try in the order: top-right, top, top-left.
}
else if (overflows.positionRight.right && overflows.positionRight.bottom) {
if (overflows.positionTopRight.right && overflows.positionTop.right) {
return PopoverPlacement.TopLeft;
}
else if (overflows.positionTopRight.right) {
return PopoverPlacement.Top;
}
else {
return PopoverPlacement.TopRight;
}
// If it only overflows on the right, try all top positions from right to left, then try all bottom positions right to left.
}
else if (overflows.positionRight.right) {
if (overflows.positionTop.top) {
if (overflows.positionBottom.right) {
return PopoverPlacement.BottomLeft;
}
else if (overflows.positionBottomRight.right) {
return PopoverPlacement.Bottom;
}
else {
return PopoverPlacement.BottomRight;
}
}
else {
if (overflows.positionTop.right) {
return PopoverPlacement.TopLeft;
}
else if (overflows.positionTopRight.right) {
return PopoverPlacement.Top;
}
else {
return PopoverPlacement.TopRight;
}
}
// If it only over flows on the top, go bottom-right.
}
else if (overflows.positionRight.top) {
return PopoverPlacement.BottomRight;
// If it only overflows on the bottom, go top-right.
}
else if (overflows.positionRight.bottom) {
return PopoverPlacement.TopRight;
}
else {
return PopoverPlacement.Right;
}
}
if (desiredPlacement === PopoverPlacement.BottomRight) {
// If it overflows on the bottom AND the right, try in the order: top, top-left, left.
if (overflows.positionBottomRight.bottom && overflows.positionBottomRight.right) {
if (overflows.positionTop.top) {
return PopoverPlacement.Left;
}
else if (overflows.positionTop.right) {
return PopoverPlacement.TopLeft;
}
else {
return PopoverPlacement.Top;
}
// If it only overflows on the bottom, try in the order: right, top-right.
}
else if (overflows.positionBottomRight.bottom) {
if (overflows.positionRight.bottom) {
return PopoverPlacement.TopRight;
}
else {
return PopoverPlacement.Right;
}
// If it only overflows on the right, try in the order: bottom, bottom-left.
}
else if (overflows.positionBottomRight.right) {
if (overflows.positionBottom.right) {
return PopoverPlacement.BottomLeft;
}
else {
return PopoverPlacement.Bottom;
}
}
else {
return PopoverPlacement.BottomRight;
}
}
if (desiredPlacement === PopoverPlacement.Bottom) {
// If it overflows on the bottom AND left, go to top-right.
if (overflows.positionBottom.bottom && overflows.positionBottom.left) {
return PopoverPlacement.TopRight;
// If it overflows on the bottom AND right, go to top-left.
}
else if (overflows.positionBottom.bottom && overflows.positionBottom.right) {
return PopoverPlacement.TopLeft;
// If it only overflows on the bottom, go to top.
}
else if (overflows.positionBottom.bottom) {
return PopoverPlacement.Top;
// If it only overflows to the right, go to bottom-left.
}
else if (overflows.positionBottom.right) {
return PopoverPlacement.BottomLeft;
// If it only overflows to the left, go to bottom-right.
}
else if (overflows.positionBottom.left) {
return PopoverPlacement.BottomRight;
}
else {
return PopoverPlacement.Bottom;
}
}
if (desiredPlacement === PopoverPlacement.BottomLeft) {
// If it overflows on the bottom AND the left, try in the order: top, top-right, right.
if (overflows.positionBottomLeft.bottom && overflows.positionBottomLeft.left) {
if (overflows.positionTop.top) {
return PopoverPlacement.Right;
}
else if (overflows.positionTop.left) {
return PopoverPlacement.TopRight;
}
else {
return PopoverPlacement.Top;
}
// If it only overflows on the bottom, try in the order: left, top-left.
}
else if (overflows.positionBottomLeft.bottom) {
if (overflows.positionLeft.bottom) {
return PopoverPlacement.TopLeft;
}
else {
return PopoverPlacement.Left;
}
// If it only overflows on the left, try in the order: bottom, bottom-right.
}
else if (overflows.positionBottomLeft.left) {
if (overflows.positionBottom.left) {
return PopoverPlacement.BottomRight;
}
else {
return PopoverPlacement.Bottom;
}
}
else {
return PopoverPlacement.BottomLeft;
}
}
if (desiredPlacement === PopoverPlacement.Left) {
// If it overflows on the left AND the top, try in the order: bottom-left, bottom, bottom-right.
if (overflows.positionLeft.left && overflows.positionLeft.top) {
if (overflows.positionBottomLeft.left && overflows.positionBottom.left) {
return PopoverPlacement.BottomRight;
}
else if (overflows.positionBottomRight.right) {
return PopoverPlacement.Bottom;
}
else {
return PopoverPlacement.BottomLeft;
}
// If it overflows on the left AND the bottom, try in the order: top-left, top, top-right.
}
else if (overflows.positionLeft.left && overflows.positionLeft.bottom) {
if (overflows.positionTopLeft.left && overflows.positionTop.left) {
return PopoverPlacement.TopRight;
}
else if (overflows.positionTopLeft.left) {
return PopoverPlacement.Top;
}
else {
return PopoverPlacement.TopLeft;
}
// If it only overflows on the left, try all top positions from left to right, then try all bottom positions left to right.
}
else if (overflows.positionLeft.left) {
if (overflows.positionTop.top) {
if (overflows.positionBottom.left) {
return PopoverPlacement.BottomRight;
}
else if (overflows.positionBottomLeft.left) {
return PopoverPlacement.Bottom;
}
else {
return PopoverPlacement.BottomLeft;
}
}
else {
if (overflows.positionTop.left) {
return PopoverPlacement.TopRight;
}
else if (overflows.positionTopLeft.left) {
return PopoverPlacement.Top;
}
else {
return PopoverPlacement.TopLeft;
}
}
// If it only over flows on the top, go bottom-left.
}
else if (overflows.positionLeft.top) {
return PopoverPlacement.BottomLeft;
// If it only overflows on the bottom, go top-left.
}
else if (overflows.positionLeft.bottom) {
return PopoverPlacement.TopLeft;
}
else {
return PopoverPlacement.Left;
}
}
if (desiredPlacement === PopoverPlacement.TopLeft) {
// If it overflows on the top AND the left, try in the order: bottom, Bottom-right, right.
if (overflows.positionTopLeft.top && overflows.positionTopLeft.left) {
if (overflows.positionBottom.bottom) {
return PopoverPlacement.Right;
}
else if (overflows.positionBottom.left) {
return PopoverPlacement.BottomRight;
}
else {
return PopoverPlacement.Bottom;
}
// If it only overflows on the top, try in the order: left, bottom-left.
}
else if (overflows.positionTopLeft.top) {
if (overflows.positionLeft.top) {
return PopoverPlacement.BottomLeft;
}
else {
return PopoverPlacement.Left;
}
// If it only overflows on the left, try in the order: top, top-right.
}
else if (overflows.positionTopLeft.left) {
if (overflows.positionTop.left) {
return PopoverPlacement.TopRight;
}
else {
return PopoverPlacement.Top;
}
}
else {
return PopoverPlacement.TopLeft;
}
}
return desiredPlacement;
};
PopoverContentComponent.decorators = [
{ type: Component, args: [{
selector: 'popover-content',
template: "\n <div #popoverDiv\n class=\"bs-popover-{{ effectivePlacement }} popover-content popover {{ parentClass }}\"\n [ngClass]=\"{\n 'sm': size === 'small',\n 'md-sm': size === 'medium-small',\n 'md': size === 'medium',\n 'lg': size === 'large',\n 'in': isIn\n }\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\"\n [style.transition]=\"(transitionEnabled ? '0.15s opacity' : '')\"\n [style.opacity]=\"opacity\"\n [style.display]=\"'block'\"\n [attr.aria-hidden]=\"opacity === 0\"\n role=\"popover\">\n <div [hidden]=\"!closeOnMouseOutside\" class=\"virtual-area\"></div>\n <div class=\"arrow\"></div>\n <div class=\"popover-header\" [hidden]=\"!title\">{{ title }}</div>\n <div class=\"popover-body\">\n <ng-content></ng-content>\n {{ content }}\n </div>\n </div>\n "
}] }
];
/** @nocollapse */
PopoverContentComponent.ctorParameters = function () { return [
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: Renderer2 }
]; };
PopoverContentComponent.propDecorators = {
content: [{ type: Input }],
placement: [{ type: Input }],
title: [{ type: Input }],
parentClass: [{ type: Input }],
animation: [{ type: Input }],
closeOnClickOutside: [{ type: Input }],
closeOnMouseOutside: [{ type: Input }],
appendToBody: [{ type: Input }],
size: [{ type: Input }],
popoverDiv: [{ type: ViewChild, args: ['popoverDiv', { static: true },] }],
onResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }]
};
return PopoverContentComponent;
}());
/**
* @fileoverview added by tsickle
* Generated from: lib/popover.directive.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* \@group Basic Toolkit
* \@component Popover Directive
*/
var PopoverDirective = /** @class */ (function () {
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
function PopoverDirective(viewContainerRef, cdr, resolver, appRef, injector) {
this.viewContainerRef = viewContainerRef;
this.cdr = cdr;
this.resolver = resolver;
this.appRef = appRef;
this.injector = injector;
// -------------------------------------------------------------------------
// Properties
// -------------------------------------------------------------------------
this.popoverContentComponent = PopoverContentComponent;
this.popoverOnHover = true;
this.popoverDismissTimeout = 0;
this.onShown = new EventEmitter();
this.onHidden = new EventEmitter();
}
// -------------------------------------------------------------------------
// Event listeners
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Event listeners
// -------------------------------------------------------------------------
/**
* @param {?} evt
* @return {?}
*/
PopoverDirective.prototype.showOrHideOnClick =
// -------------------------------------------------------------------------
// Event listeners
// -------------------------------------------------------------------------
/**
* @param {?} evt
* @return {?}
*/
function (evt) {
if (this.popoverOnHover) {
return;
}
if (this.popoverDisabled) {
return;
}
evt.stopImmediatePropagation();
this.toggle();
};
/**
* @param {?} evt
* @return {?}
*/
PopoverDirective.prototype.showOrHideOnTouch = /**
* @param {?} evt
* @return {?}
*/
function (evt) {
evt.stopImmediatePropagation();
if (!this.popoverOnHover) {
return;
}
if (this.popoverDisabled) {
return;
}
this.toggle();
};
/**
* @return {?}
*/
PopoverDirective.prototype.showOnHover = /**
* @return {?}
*/
function () {
if (!this.popoverOnHover) {
return;
}
if (this.popoverDisabled) {
return;
}
this.show();
};
/**
* @return {?}
*/
PopoverDirective.prototype.hideOnHover = /**
* @return {?}
*/
function () {
if (this.popoverCloseOnMouseOutside) {
return; // don't do anything since we do not control this
}
if (!this.popoverOnHover) {
return;
}
if (this.popoverDisabled) {
return;
}
this.hide();
};
/**
* @param {?} changes
* @return {?}
*/
PopoverDirective.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (changes['popoverDisabled']) {
if (changes['popoverDisabled'].currentValue) {
this.hide();
}
}
};
/**
* @protected
* @param {?} component
* @return {?}
*/
PopoverDirective.prototype.createComponent = /**
* @protected
* @param {?} component
* @return {?}
*/
function (component) {
/** @type {?} */
var factory = this.resolver.resolveComponentFactory(component);
// Create a component reference from the component
/** @type {?} */
var componentRef = this.appendToBody
? factory.create(this.injector)
: this.viewContainerRef.createComponent(factory);
if (this.appendToBody) {
// Attach component to the appRef so that it's inside the ng component tree
this.appRef.attachView(componentRef.hostView);
// Get DOM element from component
/** @type {?} */
var domElem = (/** @type {?} */ (((/** @type {?} */ (componentRef.hostView)))
.rootNodes[0]));
// Append DOM element to the body
document.body.appendChild(domElem);
}
return componentRef;
};
/**
* @protected
* @param {?} componentRef
* @return {?}
*/
PopoverDirective.prototype.removeComponent = /**
* @protected
* @param {?} componentRef
* @return {?}
*/
function (componentRef) {
if (this.popover) {
if (this.appendToBody) {
this.appRef.detachView(componentRef.hostView);
}
componentRef.destroy();
}
};
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* @return {?}
*/
PopoverDirective.prototype.toggle =
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* @return {?}
*/
function () {
if (!this.visible) {
this.show();
}
else {
this.hide();
}
};
/**
* @return {?}
*/
PopoverDirective.prototype.show = /**
* @return {?}
*/
function () {
var _this = this;
if (this.visible) {
return;
}
this.visible = true;
if (typeof this.content === 'string') {
if (!this.visible) {
return;
}
this.popover = this.createComponent(this.popoverContentComponent);
/** @type {?} */
var popover = (/** @type {?} */ (this.popover.instance));
popover.popover = this;
popover.content = (/** @type {?} */ (this.content));
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;
}
if (this.popoverSize) {
popover.size = this.popoverSize;
}
popover.appendToBody = this.appendToBody;
popover.onCloseFromOutside.subscribe((/**
* @return {?}
*/
function () { return _this.hide(); }));
// if dismissTimeout option is set, then this popover will be dismissed in dismissTimeout time
if (this.popoverDismissTimeout > 0) {
setTimeout((/**
* @return {?}
*/
function () { return _this.hide(); }), this.popoverDismissTimeout);
}
}
else {
/** @type {?} */
var popover = (/** @type {?} */ (this.content));
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;
}
if (this.popoverSize) {
popover.size = this.popoverSize;
}
popover.appendToBody = this.appendToBody;
popover.onCloseFromOutside.subscribe((/**
* @return {?}
*/
function () { return _this.hide(); }));
// if dismissTimeout option is set, then this popover will be dismissed in dismissTimeout time
if (this.popoverDismissTimeout > 0) {
setTimeout((/**
* @return {?}
*/
function () { return _this.hide(); }), this.popoverDismissTimeout);
}
popover.show();
}
this.cdr.detectChanges();
this.onShown.emit(this);
};
/**
* @return {?}
*/
PopoverDirective.prototype.hide = /**
* @return {?}
*/
function () {
if (!this.visible) {
return;
}
this.visible = false;
this.removeComponent(this.popover);
if (this.content instanceof PopoverContentComponent) {
((/** @type {?} */ (this.content))).hideFromPopover();
}
this.cdr.detectChanges();
this.onHidden.emit(this);
};
/**
* @return {?}
*/
PopoverDirective.prototype.getElement = /**
* @return {?}
*/
function () {
return this.viewContainerRef.element.nativeElement;
};
PopoverDirective.decorators = [
{ type: Directive, args: [{
selector: '[popover]',
exportAs: 'popover'
},] }
];
/** @nocollapse */
PopoverDirective.ctorParameters = function () { return [
{ type: ViewContainerRef },
{ type: ChangeDetectorRef },
{ type: ComponentFactoryResolver },
{ type: ApplicationRef },
{ type: Injector }
]; };
PopoverDirective.propDecorators = {
content: [{ type: Input, args: ['popover',] }],
popoverSize: [{ type: Input }],
popoverDisabled: [{ type: Input }],
popoverAnimation: [{ type: Input }],
popoverPlacement: [{ type: Input }],
popoverTitle: [{ type: Input }],
popoverOnHover: [{ type: Input }],
popoverCloseOnClickOutside: [{ type: Input }],
popoverCloseOnMouseOutside: [{ type: Input }],
popoverDismissTimeout: [{ type: Input }],
appendToBody: [{ type: Input }],
onShown: [{ type: Output }],
onHidden: [{ type: Output }],
showOrHideOnClick: [{ type: HostListener, args: ['click', ['$event'],] }],
showOrHideOnTouch: [{ type: HostListener, args: ['touchend', ['$event'],] }],
showOnHover: [{ type: HostListener, args: ['focusin',] }, { type: HostListener, args: ['mouseenter',] }],
hideOnHover: [{ type: HostListener, args: ['focusout',] }, { type: HostListener, args: ['mouseleave',] }]
};
return PopoverDirective;
}());
/**
* @fileoverview added by tsickle
* Generated from: lib/popover.module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var PopoverModule = /** @class */ (function () {
function PopoverModule() {
}
PopoverModule.decorators = [
{ type: NgModule, args: [{
declarations: [
PopoverDirective,
PopoverContentComponent
],
imports: [
CommonModule,
],
exports: [
PopoverContentComponent,
PopoverDirective
],
entryComponents: [
PopoverContentComponent
]
},] }
];
return PopoverModule;
}());
/**
* @fileoverview added by tsickle
* Generated from: public_api.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* Generated from: ngx-smart-popover.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { PopoverContentComponent, PopoverDirective, PopoverModule, PopoverPlacement };
//# sourceMappingURL=ngx-smart-popover.js.map