All files / tooltip si-tooltip.service.ts

95% Statements 19/20
0% Branches 0/1
100% Functions 6/6
94.73% Lines 18/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                                                        8x 8x 8x 8x       8x       8x 8x   8x 8x 8x   8x 8x 8x         4x       8x                         1x 10x               8x                    
/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import {
  ComponentRef,
  ElementRef,
  inject,
  Injectable,
  Injector,
  TemplateRef,
  Type
} from '@angular/core';
import { getOverlay, getPositionStrategy, positions } from '@siemens/element-ng/common';
import { TranslatableString } from '@siemens/element-translate-ng/translate';
 
import { TooltipComponent } from './si-tooltip.component';
 
/**
 * TooltipRef is attached to a specific element.
 * Use it to show or hide a tooltip for that element.
 *
 * @internal
 */
class TooltipRef {
  constructor(
    private overlayRef: OverlayRef,
    private element: ElementRef,
    private describedBy: string,
    private injector?: Injector
  ) {}
 
  show(content: TranslatableString | TemplateRef<any> | Type<any>, tooltipContext?: unknown): void {
    Iif (this.overlayRef.hasAttached()) {
      return;
    }
 
    const toolTipPortal = new ComponentPortal(TooltipComponent, undefined, this.injector);
    const tooltipRef: ComponentRef<TooltipComponent> = this.overlayRef.attach(toolTipPortal);
 
    tooltipRef.setInput('tooltip', content);
    tooltipRef.setInput('id', this.describedBy);
    tooltipRef.setInput('tooltipContext', tooltipContext);
 
    const positionStrategy = getPositionStrategy(this.overlayRef);
    positionStrategy?.positionChanges.subscribe(change =>
      tooltipRef.instance.updateTooltipPosition(change, this.element)
    );
  }
 
  hide(): void {
    this.overlayRef.detach();
  }
 
  destroy(): void {
    this.overlayRef.dispose();
  }
}
 
/**
 * A service to create tooltips for specific elements.
 * Use this if the tooltip directive is not suitable.
 * Must not be used outside element-ng.
 *
 * @internal
 */
// We cannot provide this in root, as people may override the cdk overlay creation.
@Injectable()
export class SiTooltipService {
  private overlay = inject(Overlay);
 
  createTooltip(config: {
    describedBy: string;
    element: ElementRef;
    placement: keyof typeof positions;
    injector?: Injector;
  }): TooltipRef {
    return new TooltipRef(
      getOverlay(config.element, this.overlay, false, config.placement),
      config.element,
      config.describedBy,
      config.injector
    );
  }
}
 
export type { TooltipRef };