UNPKG

@desnoth/vue2-popup

Version:

A simple Vue popup component with self state

129 lines (117 loc) 3.86 kB
export function calculatePopupPosition( origin: HTMLElement, target: HTMLElement ) { let originWidth: number = origin.offsetWidth; let originHeight: number = origin.offsetHeight; let viewportOffset = origin.getBoundingClientRect(); let targetPosition = target.getBoundingClientRect(); let position = { left: Math.round(viewportOffset.left), top: Math.round(viewportOffset.top) }; let popupWidth = target.offsetWidth; let popupHeight = target.offsetHeight; let outputLeft: number | string = position.left + originWidth / 2 - popupWidth / 2; let outputTop: number | string = position.top + originHeight; let outputBottom: number | string = "none"; let windowWidth: number = window.innerWidth; if (outputLeft + popupWidth > windowWidth - 15) { outputLeft = windowWidth - popupWidth - 15; } else if (outputLeft < 15) { outputLeft = 15; } if (outputTop + popupHeight + 15 > window.innerHeight) { outputTop = "none"; outputBottom = window.innerHeight - position.top + 15 + "px"; } else { outputTop = outputTop + 15 + "px"; } const triangleLeft = position.left - outputLeft + originWidth / 2 - 13 + "px"; return { left: outputLeft + "px", top: outputTop, bottom: outputBottom, width: originWidth + "px", triangleLeft }; } // Popup component helper export function calculatePopupRelativePosition( origin: HTMLElement, target: HTMLElement, container?: HTMLElement ) { const originWidth: number = origin.offsetWidth; const originHeight: number = origin.offsetHeight; const viewportOffset = origin.getBoundingClientRect(); let OriginPosition = { left: Math.round(viewportOffset.left), top: Math.round(viewportOffset.top) }; const popupWidth: number = target.offsetWidth; const popupHeight: number = target.offsetHeight; let containerWidth: number; let containerHeight: number; let containerPosition; let outputLeft: any; let outputTop: any; if (container) { containerWidth = container.offsetWidth; containerHeight = container.offsetHeight; containerPosition = { left: Math.round(container.getBoundingClientRect().left), top: Math.round(container.getBoundingClientRect().top) }; OriginPosition = { left: OriginPosition.left - containerPosition.left, top: OriginPosition.top - containerPosition.top }; } else { containerWidth = window.innerWidth; containerHeight = window.innerHeight; containerPosition = { left: 0, top: 0 }; OriginPosition = { left: Math.round(viewportOffset.left), top: Math.round(viewportOffset.top) }; } outputLeft = OriginPosition.left + originWidth / 2 - popupWidth / 2; outputTop = OriginPosition.top + originHeight + 15; let XType; let YType; // check left and right if (popupWidth + 15 > containerWidth) { XType = "fill"; } else if (outputLeft + popupWidth > containerWidth - 15) { XType = "right"; } else if (outputLeft < 15) { XType = "left"; } else { XType = "center"; } // check top and bottom const topMargin = outputTop + popupHeight + 15; const bottomMargin = containerHeight - OriginPosition.top + popupHeight + 15; let maxHeight = null; if (topMargin < containerHeight) { YType = "bottom"; maxHeight = containerHeight - outputTop - 15; } else if (bottomMargin < containerHeight) { YType = "top"; maxHeight = containerHeight - (containerHeight - OriginPosition.top) - 15; } else { if ( containerHeight - outputTop > containerHeight - (containerHeight - OriginPosition.top) ) { YType = "bottom"; maxHeight = containerHeight - outputTop - 15; } else { YType = "top"; maxHeight = containerHeight - (containerHeight - OriginPosition.top) - 15; } } return { XType, YType, maxHeight }; }