mseemann/angular2-mdl

View on GitHub
projects/core/src/lib/tooltip/mdl-tooltip.directive.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
import {
  ComponentFactoryResolver,
  ComponentRef,
  Directive,
  HostListener,
  Input,
  OnChanges,
  OnInit,
  SimpleChanges,
  ViewContainerRef,
} from "@angular/core";
import {
  MdlSimpleTooltipComponent,
  MdlTooltipComponent,
} from "./mdl-tooltip.component";

@Directive()
export abstract class AbstractMdlTooltipDirective implements OnInit, OnChanges {
  protected tooltip: string | MdlTooltipComponent | undefined;
  protected position: "left" | "right" | "top" | "bottom" = "top";

  protected tooltipComponent: MdlSimpleTooltipComponent | undefined;

  protected constructor(
    private vcRef: ViewContainerRef,
    private large: boolean,
    private componentFactoryResolver: ComponentFactoryResolver
  ) {}

  @HostListener("touchend", ["$event"])
  @HostListener("mouseenter", ["$event"])
  onMouseEnter(event: MouseEvent): void {
    this.tooltipComponent?.mouseEnter(event);
  }

  @HostListener("window:touchstart")
  @HostListener("mouseleave")
  onMouseLeave(): void {
    this.tooltipComponent?.mouseLeave();
  }

  ngOnInit(): void {
    // if the tooltip is not an instance of MdlTooltipComponent
    // we create a simpleTooltipComponent on the fly.
    if (!(this.tooltip instanceof MdlTooltipComponent)) {
      const cFactory = this.componentFactoryResolver.resolveComponentFactory(
        MdlSimpleTooltipComponent
      );
      const cRef: ComponentRef<MdlSimpleTooltipComponent> =
        this.vcRef.createComponent(cFactory);

      this.tooltipComponent = cRef.instance as MdlSimpleTooltipComponent;
      if (this.tooltipComponent) {
        this.tooltipComponent.tooltipText = this.tooltip;
      }
      this.configureTooltipComponent();
    } else {
      this.tooltipComponent = this.tooltip;
      this.configureTooltipComponent();
    }
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes["tooltip"] && !changes["tooltip"].isFirstChange()) {
      if (!(this.tooltip instanceof MdlTooltipComponent)) {
        if (this.tooltipComponent) {
          this.tooltipComponent.tooltipText = this.tooltip;
        }
      }
    }
  }

  private configureTooltipComponent() {
    if (this.tooltipComponent) {
      this.tooltipComponent.large = this.large;
      this.tooltipComponent.position = this.position;
    }
  }
}

@Directive({
  // eslint-disable-next-line
  selector: "[mdl-tooltip]",
})
export class MdlTooltipDirective extends AbstractMdlTooltipDirective {
  @Input("mdl-tooltip") public override tooltip:
    | string
    | MdlTooltipComponent
    | undefined;
  // eslint-disable-next-line @angular-eslint/no-input-rename
  @Input("mdl-tooltip-position") public override position:
    | "left"
    | "right"
    | "top"
    | "bottom" = "top";

  constructor(
    vcRef: ViewContainerRef,
    componentFactoryResolver: ComponentFactoryResolver
  ) {
    super(vcRef, false, componentFactoryResolver);
  }
}

@Directive({
  // eslint-disable-next-line
  selector: "[mdl-tooltip-large]",
})
export class MdlTooltipLargeDirective extends AbstractMdlTooltipDirective {
  @Input("mdl-tooltip-large") public override tooltip:
    | string
    | MdlTooltipComponent
    | undefined;
  // eslint-disable-next-line @angular-eslint/no-input-rename
  @Input("mdl-tooltip-position") public override position:
    | "left"
    | "right"
    | "top"
    | "bottom" = "top";

  constructor(
    vcRef: ViewContainerRef,
    componentFactoryResolver: ComponentFactoryResolver
  ) {
    super(vcRef, true, componentFactoryResolver);
  }
}