How to add line break to custom tooltip directive using angular 7

412 Views Asked by At

I am new to angular 7 directives. I created a custom tooltip directive using angular 7. Now, I am unable to specify line breaks when i pass the tooltip text from my html. I want a line break after the Tootltip Title text I pass from html. Any idea how to achieve this? Tried to pass 
 and 
 code for line break in my input string to the tooltip directive. Didn't work either.

Here is what I tried so far.

My directive : tooltip.directive.ts:

import { Directive, Input, ElementRef, HostListener, Renderer2 } from '@angular/core';
@Directive({
  selector: '[tooltip]'
})
export class TooltipDirective {
  @Input('tooltip') tooltipTitle: string;
  @Input() placement: string;
  @Input() delay: number;
  tooltip: HTMLElement;
  offset = 10;

  constructor(private el: ElementRef, private renderer: Renderer2) { }

  @HostListener('mouseenter') onMouseEnter() {
    if (!this.tooltip) { this.show(); }
  }

  @HostListener('mouseleave') onMouseLeave() {
    if (this.tooltip) { this.hide(); }
  }

  show() {
    this.create();
    this.setPosition();
    this.renderer.addClass(this.tooltip, 'ng-tooltip-show');
  }

  hide() {
    this.renderer.removeClass(this.tooltip, 'ng-tooltip-show');
    window.setTimeout(() => {
      this.renderer.removeChild(document.body, this.tooltip);
      this.tooltip = null;
    }, 0);
  }

  create() {
    this.tooltip = this.renderer.createElement('span');

    this.renderer.appendChild(
      this.tooltip,
      this.renderer.createText(this.tooltipTitle) // textNode
    );

    this.renderer.appendChild(document.body, this.tooltip);

    this.renderer.addClass(this.tooltip, 'ng-tooltip');
    this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`);
  }

  setPosition() {
    const hostPos = this.el.nativeElement.getBoundingClientRect();
    const tooltipPos = this.tooltip.getBoundingClientRect();

    let top, left;

    if (this.placement === 'top') {
      top = hostPos.top - tooltipPos.height - this.offset;
      left = hostPos.left + (hostPos.width - tooltipPos.width) / 2;
    }
   /* other positions to be added */
    this.renderer.setStyle(this.tooltip, 'top', `${top}px`);
    this.renderer.setStyle(this.tooltip, 'left', `${left}px`);
  }
}

CSS :

/* Styles for tooltip */
.ng-tooltip {
  position: absolute;
  max-width: 150px;
  font-size: 14px;
  text-align: center;
  color: #f8f8f2;
  padding: 3px 8px;
  border-radius: 2px;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.5);
  background-color: #38393b;
  z-index: 1000;
  opacity: 0;
}
.ng-tooltip:after {
  content: "";
  position: absolute;
  border-style: solid;
}
.ng-tooltip-top:after {
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-color: #38393b transparent transparent transparent;
}

.ng-tooltip-show {
  opacity: 1;
}

From the html file, I invoke the tooltip directive by passing the text like this:

  <div tooltip="Title: ( want a line break here) &#013; {{someVariable}}" placement="top" class="remark">Hover Here</div>
1

There are 1 best solutions below

0
On

This can be resolved by taking any of the approach, Either create two different input such as @Input('Title'): string and @Input('Body'): string and pass into two different parameters. OR if you want to pass it in a single parameter make a use of interface such as

export interface IToolTip {
    title?: string;
    body: string;
    footer?: string;
}

Assign this interface to your tooltip variable @Input('tooltip') tooltipTitle: ITooltip; Rest of the things can taken care under create() funciton.

Thanks.