@ipi-soft/ng-components
Version:
Custom Angular Components
297 lines (293 loc) • 13.1 kB
JavaScript
import { DOCUMENT } from '@angular/common';
import * as i0 from '@angular/core';
import { Directive, Inject, Input, HostListener } from '@angular/core';
import * as i1 from '@ipi-soft/ng-components/services';
import { MobileOS } from '@ipi-soft/ng-components/services';
var TooltipPosition;
(function (TooltipPosition) {
TooltipPosition[TooltipPosition["Before"] = 0] = "Before";
TooltipPosition[TooltipPosition["After"] = 1] = "After";
TooltipPosition[TooltipPosition["Above"] = 2] = "Above";
TooltipPosition[TooltipPosition["Below"] = 3] = "Below";
})(TooltipPosition || (TooltipPosition = {}));
class IpiTooltipDirective {
constructor(osService, elementRef, overlayService, document) {
this.osService = osService;
this.elementRef = elementRef;
this.overlayService = overlayService;
this.document = document;
this.ipiTooltip = '';
this.tooltipPosition = TooltipPosition.Before;
this.isActivated = false;
this.triangleWidth = 8;
this.errorMargin = 2;
this.platform = this.osService.mobileOS;
}
ngOnDestroy() {
this.onMouseLeave();
}
onMouseEnter() {
this.elementRef.nativeElement.style.touchAction = 'manipulation';
this.parentElementPos = this.getParentElementPosition();
this.openToolTip();
}
onMouseLeave() {
this.elementRef.nativeElement.style.touchAction = 'auto';
this.closeToolTip();
}
onResize() {
this.closeToolTip();
}
onTouchStart(event) {
event.preventDefault();
this.elementRef.nativeElement.style.userSelect = 'none';
this.parentElementPos = this.getParentElementPosition();
this.openToolTip();
}
onTouchEnd() {
this.closeToolTip();
}
onTouchCancel() {
this.closeToolTip();
}
onScroll() {
if (this.isActivated) {
this.parentElementPos = this.getParentElementPosition();
let parentPosTop = this.parentElementPos.top;
const tooltipElement = document.querySelector('.tooltip-wrapper');
if (this.platform === MobileOS.iOS) {
parentPosTop += window.visualViewport.offsetTop;
}
tooltipElement.style.top = `${parentPosTop}px`;
}
}
getParentElementPosition() {
return this.elementRef.nativeElement.getBoundingClientRect();
}
openToolTip() {
this.createTooltip();
this.createTriangle();
this.createTooltipWrapper();
this.tooltipWrapper.appendChild(this.tooltip);
this.tooltipWrapper.appendChild(this.triangle);
this.overlayService.appendToOverlay(this.tooltipWrapper);
this.positionTooltip();
this.isActivated = true;
}
closeToolTip() {
if (this.tooltipWrapper) {
this.overlayService.removeFromOverlay(this.tooltipWrapper);
this.isActivated = false;
}
}
createTooltip() {
this.tooltip = this.document.createElement('div');
this.tooltip.classList.add('tooltip');
this.tooltip.innerHTML = this.ipiTooltip;
this.tooltip.style.gap = '10px';
this.tooltip.style.color = 'white';
this.tooltip.style.minWidth = '50px';
this.tooltip.style.minHeight = '10px';
this.tooltip.style.fontSize = '12px';
this.tooltip.style.fontWeight = '400';
this.tooltip.style.maxWidth = '200px';
this.tooltip.style.lineHeight = '16px';
this.tooltip.style.padding = '4px 8px';
this.tooltip.style.textAlign = 'center';
this.tooltip.style.borderRadius = '4px';
this.tooltip.style.whiteSpace = 'pre-wrap';
this.tooltip.style.wordBreak = 'break-word';
this.tooltip.style.backgroundColor = '#0B1222';
}
createTriangle() {
this.triangle = this.document.createElement('div');
this.triangle.classList.add('triangle');
this.triangle.style.width = '0';
this.triangle.style.height = '0';
this.triangle.style.content = '';
this.triangle.style.borderRight = '8px solid #0B1222';
this.triangle.style.borderTop = '5px solid transparent';
this.triangle.style.borderBottom = '5px solid transparent';
}
createTooltipWrapper() {
this.tooltipWrapper = this.document.createElement('div');
this.tooltipWrapper.classList.add('tooltip-wrapper');
this.tooltipWrapper.style.display = 'flex';
this.tooltipWrapper.style.position = 'absolute';
this.tooltipWrapper.style.alignItems = 'center';
const keyframes = [
{ opacity: 0 },
{ opacity: 1 }
];
this.tooltipWrapper.animate(keyframes, {
duration: 400,
easing: 'ease'
});
}
positionTooltip() {
if (this.overlayService.overlay) {
this.tooltipWidth = this.overlayService.overlay.querySelector('.tooltip-wrapper')?.firstElementChild?.clientWidth || 0;
}
switch (this.tooltipPosition) {
case TooltipPosition.Before:
this.positionBefore();
break;
case TooltipPosition.After:
this.positionAfter();
break;
case TooltipPosition.Above:
this.positionAbove();
break;
case TooltipPosition.Below:
this.positionBelow();
break;
}
this.repositionTooltip();
}
positionBefore() {
let parentPosTop = this.parentElementPos.top;
let parentPosLeft = this.parentElementPos.left;
this.tooltipWrapper.style.flexDirection = 'row';
this.triangle.style.transform = 'rotate(180deg)';
this.tooltipWrapper.style.transform = `translateY(${this.parentElementPos.height / 2}px) translateY(-50%)`;
if (this.platform === MobileOS.iOS) {
parentPosTop += window.visualViewport.offsetTop;
parentPosLeft += window.visualViewport.offsetLeft;
}
this.tooltipWrapper.style.left = `${parentPosLeft - this.tooltipWidth - this.triangleWidth}px`;
this.tooltipWrapper.style.top = `${parentPosTop}px`;
}
positionAfter() {
let parentPosTop = this.parentElementPos.top;
let parentPosRight = this.parentElementPos.right;
this.triangle.style.transform = 'rotate(0deg)';
this.tooltipWrapper.style.flexDirection = 'row-reverse';
this.tooltipWrapper.style.transform = `translateY(${this.parentElementPos.height / 2}px) translateY(-50%)`;
if (this.platform === MobileOS.iOS) {
parentPosTop += window.visualViewport.offsetTop;
parentPosRight += window.visualViewport.offsetLeft;
}
this.tooltipWrapper.style.top = `${parentPosTop}px`;
this.tooltipWrapper.style.left = `${parentPosRight}px`;
}
positionAbove() {
let parentPosTop = this.parentElementPos.top;
let parentPosLeft = this.parentElementPos.left;
this.tooltipWrapper.style.flexDirection = 'column';
this.tooltipWrapper.style.transform = 'translateY(-100%)';
this.tooltipWrapper.style.transform = 'translateY(-100%)';
if (this.platform === MobileOS.iOS) {
parentPosTop += window.visualViewport.offsetTop;
parentPosLeft += window.visualViewport.offsetLeft;
}
this.tooltipWrapper.style.top = `${parentPosTop}px`;
this.tooltipWrapper.style.left = ` ${(parentPosLeft + this.parentElementPos.width / 2) - this.tooltipWidth / 2}px`;
this.triangle.style.transform = 'rotate(-90deg) translateX(1px)';
}
positionBelow() {
let parentPosTop = this.parentElementPos.top;
let parentPosLeft = this.parentElementPos.left;
this.tooltipWrapper.style.flexDirection = 'column-reverse';
this.triangle.style.transform = 'rotate(90deg) translateX(1px)';
this.tooltipWrapper.style.transform = `translateY(${this.parentElementPos.height}px)`;
if (this.platform === MobileOS.iOS) {
parentPosTop += window.visualViewport.offsetTop;
parentPosLeft += window.visualViewport.offsetLeft;
}
this.tooltipWrapper.style.top = ` ${parentPosTop}px`;
this.tooltipWrapper.style.left = ` ${(parentPosLeft + this.parentElementPos.width / 2) - this.tooltipWidth / 2}px`;
}
repositionTooltip() {
const tooltipPosition = this.tooltipWrapper.getBoundingClientRect();
let tooltipX = tooltipPosition.x;
if (this.platform === MobileOS.iOS) {
tooltipX += window.visualViewport.offsetLeft;
}
switch (this.tooltipPosition) {
case TooltipPosition.Before:
if (tooltipPosition.x < 0) {
this.positionAfter();
}
if (window.innerWidth - tooltipPosition.right <= tooltipPosition.width) {
this.positionAbove();
}
break;
case TooltipPosition.After:
if (window.innerWidth < tooltipX + tooltipPosition.width) {
this.positionBefore();
}
if (tooltipPosition.width > this.parentElementPos.left) {
this.positionAbove();
}
break;
case TooltipPosition.Above:
if (tooltipX < 0) {
this.positionAfter();
break;
}
if (tooltipPosition.left > window.innerWidth / 2 && (tooltipPosition.left + tooltipPosition.width / 2) + this.errorMargin < this.parentElementPos.left + this.parentElementPos.width / 2) {
this.positionBefore();
break;
}
if (this.parentElementPos.top < tooltipPosition.height) {
this.positionBelow();
}
break;
case TooltipPosition.Below:
if (tooltipX < 0) {
this.positionAfter();
break;
}
if (tooltipPosition.left > window.innerWidth / 2 && (tooltipPosition.left + tooltipPosition.width / 2) + this.errorMargin < this.parentElementPos.left + this.parentElementPos.width / 2) {
this.positionBefore();
break;
}
if (window.innerHeight - this.parentElementPos.bottom < tooltipPosition.height) {
this.positionAbove();
}
break;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: IpiTooltipDirective, deps: [{ token: i1.OSService }, { token: i0.ElementRef }, { token: i1.OverlayService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.4", type: IpiTooltipDirective, isStandalone: true, selector: "[ipiTooltip]", inputs: { ipiTooltip: "ipiTooltip", tooltipPosition: "tooltipPosition" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "window:resize": "onResize()", "touchstart": "onTouchStart($event)", "touchend": "onTouchEnd()", "touchcancel": "onTouchCancel()", "window:scroll": "onScroll($event)" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: IpiTooltipDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: '[ipiTooltip]'
}]
}], ctorParameters: () => [{ type: i1.OSService }, { type: i0.ElementRef }, { type: i1.OverlayService }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { ipiTooltip: [{
type: Input
}], tooltipPosition: [{
type: Input
}], onMouseEnter: [{
type: HostListener,
args: ['mouseenter']
}], onMouseLeave: [{
type: HostListener,
args: ['mouseleave']
}], onResize: [{
type: HostListener,
args: ['window:resize']
}], onTouchStart: [{
type: HostListener,
args: ['touchstart', ['$event']]
}], onTouchEnd: [{
type: HostListener,
args: ['touchend']
}], onTouchCancel: [{
type: HostListener,
args: ['touchcancel']
}], onScroll: [{
type: HostListener,
args: ['window:scroll', ['$event']]
}] } });
/**
* Generated bundle index. Do not edit.
*/
export { IpiTooltipDirective, TooltipPosition };
//# sourceMappingURL=ipi-soft-ng-components-tooltip.mjs.map