Интеграция с Angular

Для использования Tippy.js в Angular-проектах необходимо сначала установить саму библиотеку и её зависимости. Выполняется это через npm:

npm install tippy.js
npm install @popperjs/core

@popperjs/core необходим для корректного позиционирования всплывающих подсказок. После установки библиотек их нужно импортировать в компонент, где планируется использовать всплывающие подсказки:

import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';

Импорт CSS обязательный для базовой стилизации тултипов.


Инициализация Tippy.js на элементах Angular

Для интеграции с Angular обычно используются методы жизненного цикла компонентов. Самый удобный способ — инициализация в методе ngAfterViewInit, чтобы элементы DOM были уже полностью загружены.

import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';

@Component({
  selector: 'app-tooltip-demo',
  template: `
    <button #tooltipButton>Наведите на меня</button>
  `
})
export class TooltipDemoComponent implements AfterViewInit {
  @ViewChild('tooltipButton') button!: ElementRef;

  ngAfterViewInit(): void {
    tippy(this.button.nativeElement, {
      content: 'Пример подсказки',
      placement: 'top',
      animation: 'fade',
      delay: [100, 100]
    });
  }
}

Ключевые моменты:

  • @ViewChild позволяет получить доступ к DOM-элементу.
  • placement определяет позицию тултипа относительно элемента (top, bottom, left, right и их варианты с -start, -end).
  • animation задает анимацию появления.
  • delay — массив [появление, скрытие] в миллисекундах.

Использование директив Angular для Tippy.js

Для более чистой интеграции с Angular часто создают собственные директивы, которые оборачивают функционал Tippy.js. Это позволяет использовать тултипы декларативно прямо в шаблоне.

import { Directive, Input, ElementRef, AfterViewInit } from '@angular/core';
import tippy, { Instance, Props } from 'tippy.js';

@Directive({
  selector: '[appTippy]'
})
export class TippyDirective implements AfterViewInit {
  @Input('appTippy') content!: string;
  @Input() placement: Props['placement'] = 'top';

  private instance!: Instance;

  constructor(private el: ElementRef) {}

  ngAfterViewInit(): void {
    this.instance = tippy(this.el.nativeElement, {
      content: this.content,
      placement: this.placement
    });
  }

  ngOnDestroy(): void {
    this.instance.destroy();
  }
}

Применение директивы в шаблоне:

<button appTippy="Подсказка с директивой" placement="right">Наведите на меня</button>

Преимущества директивы:

  • Сохраняет декларативность Angular-шаблонов.
  • Управление тултипом сосредоточено в одном месте.
  • Возможность расширения с кастомными параметрами (анимация, триггеры, delay).

Настройка триггеров и интерактивных тултипов

Tippy.js поддерживает разные типы триггеров: mouseenter, click, focus и их комбинации. Для интерактивных элементов, например, выпадающих подсказок с кнопками внутри, необходимо указать interactive: true.

tippy('#interactiveButton', {
  content: '<button>Кликни меня</button>',
  allowHTML: true,
  interactive: true,
  placement: 'bottom'
});

Важные параметры:

  • allowHTML — разрешает вставку HTML-контента.
  • interactive — предотвращает скрытие тултипа при наведении на его содержимое.
  • Можно комбинировать trigger: 'click mouseenter' для более гибкого поведения.

Управление состоянием тултипов в Angular

Tippy.js предоставляет API для программного контроля тултипов через экземпляр:

let tip = tippy('#manualButton', { content: 'Ручное управление' });

// Показать тултип
tip.show();

// Скрыть тултип
tip.hide();

// Переключить видимость
tip.toggle();

// Изменить контент динамически
tip.setContent('Новый текст');

В Angular это удобно использовать с @ViewChild и EventEmitter для синхронизации с логикой компонентов:

@ViewChild('manualButton') manualBtn!: ElementRef;

showTooltip() {
  const instance = tippy(this.manualBtn.nativeElement, { content: 'Динамический текст' });
  instance.show();
}

Интеграция с динамическими компонентами и списками

Для элементов, создаваемых через *ngFor, нужно инициализировать Tippy.js после рендеринга всех элементов. Это делается с помощью @ViewChildren и метода ngAfterViewInit:

@ViewChildren('tooltipItem') items!: QueryList<ElementRef>;

ngAfterViewInit(): void {
  this.items.forEach(item => {
    tippy(item.nativeElement, { content: 'Элемент списка' });
  });
}

Такой подход гарантирует, что тултипы корректно привязаны ко всем элементам списка.


Продвинутые настройки: темы и стили

Tippy.js поддерживает кастомные темы и стили. Для Angular удобно подключать CSS темы отдельно:

tippy('#themedButton', {
  content: 'Тема dark',
  theme: 'dark',
  placement: 'right'
});

Для создания собственной темы:

.tippy-box[data-theme~='custom'] {
  background-color: #333;
  color: #fff;
  border-radius: 8px;
  font-size: 14px;
  padding: 6px 10px;
}

И применение:

tippy('#customButton', {
  content: 'Собственная тема',
  theme: 'custom'
});

Оптимизация производительности в Angular

  • Инициализация тултипов только на видимых элементах.
  • Использование директив вместо множественных вызовов tippy().
  • Разрушение экземпляров в ngOnDestroy для предотвращения утечек памяти.
  • Пакетная инициализация для элементов списков через @ViewChildren вместо отдельного вызова для каждого элемента.

Этот подход обеспечивает полную интеграцию Tippy.js в Angular-приложения с управляемыми компонентами, декларативной логикой и гибкой кастомизацией.