c3-tooltipTrigger.directive.ts 2.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { Directive, forwardRef, Input, AfterViewInit, ElementRef, ViewContainerRef, OnDestroy, NgZone } from '@angular/core';
  2. import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
  3. import { C3Tooltip } from './c3-tooltip.component';
  4. import { Overlay, OverlayConfig, ScrollDispatcher, OverlayRef } from '@angular/cdk/overlay';
  5. import { Platform } from '@angular/cdk/platform';
  6. import { TemplatePortal } from '@angular/cdk/portal';
  7. export const MAT_AUTOCOMPLETE_VALUE_ACCESSOR: any = {
  8. provide: NG_VALUE_ACCESSOR,
  9. useExisting: forwardRef(() => C3TooltipTrigger),
  10. multi: true
  11. };
  12. @Directive({
  13. selector: '[c3Tooltip]',
  14. exportAs: 'c3TooltipTrigger',
  15. providers: [MAT_AUTOCOMPLETE_VALUE_ACCESSOR]
  16. })
  17. export class C3TooltipTrigger implements AfterViewInit, OnDestroy {
  18. overlayRef: OverlayRef | null;
  19. @Input('c3Tooltip') tooltip: C3Tooltip;
  20. @Input('c3TooltipDisabled') disabled: Boolean = false;
  21. /** The default delay in ms before showing the tooltip after show is called */
  22. @Input('c3TooltipShowDelay') showDelay = 0;
  23. /** The default delay in ms before hiding the tooltip after hide is called */
  24. @Input('c3TooltipHideDelay') hideDelay = 0;
  25. private _manualListeners = new Map<string, EventListenerOrEventListenerObject>();
  26. constructor(
  27. private _element: ElementRef<HTMLElement>,
  28. private _overlay: Overlay,
  29. platform: Platform,
  30. private _ngZone: NgZone,
  31. private _scrollDispatcher: ScrollDispatcher,
  32. private _viewContainerRef: ViewContainerRef) {
  33. if (!platform.IOS && !platform.ANDROID) {
  34. this._manualListeners
  35. .set('mouseenter', () => this.show())
  36. .set('mouseleave', () => this.hide());
  37. }
  38. }
  39. ngAfterViewInit() {
  40. this._manualListeners.forEach((listener, event) => this._element.nativeElement.addEventListener(event, listener));
  41. }
  42. ngOnDestroy() {
  43. this._manualListeners.forEach((listener, event) => {
  44. this._element.nativeElement.removeEventListener(event, listener);
  45. });
  46. this._manualListeners.clear();
  47. }
  48. show() {
  49. const overlayRef = this._overlay.create(this.getOverlayConfig());
  50. const portal = new TemplatePortal(this.tooltip.template, this._viewContainerRef);
  51. overlayRef.attach(portal);
  52. this.overlayRef = overlayRef;
  53. }
  54. hide() {
  55. this.overlayRef.detach();
  56. }
  57. private getOverlayConfig(): OverlayConfig {
  58. const positionStrategy = this._overlay.position()
  59. .flexibleConnectedTo(this._element)
  60. .withPositions([{
  61. originX: 'start',
  62. originY: 'top',
  63. overlayX: 'center',
  64. overlayY: 'bottom',
  65. }])
  66. .withViewportMargin(8);
  67. return new OverlayConfig({
  68. positionStrategy
  69. })
  70. }
  71. }