Создание типобезопасных оберток

Tippy.js — это мощная библиотека для создания всплывающих подсказок (tooltip) и поповер-элементов в браузере. Основная идея заключается в том, чтобы ассоциировать DOM-элемент с всплывающей подсказкой, которая может содержать текст, HTML-контент или даже интерактивные компоненты.

Создание типовой подсказки осуществляется с помощью функции tippy():

tippy('#button', {
  content: 'Нажмите здесь для действия',
  placement: 'top',
  arrow: true,
});

Здесь #button — селектор элемента, content — текст подсказки, placement задаёт позицию относительно элемента (top, bottom, left, right), а arrow: true добавляет стрелку к подсказке.

Конфигурация и опции

Tippy.js предоставляет множество настроек, позволяющих гибко управлять поведением подсказок:

  • trigger — событие, при котором появляется подсказка (mouseenter, click, focus, manual).
  • interactive — если true, подсказка может содержать интерактивные элементы (ссылки, кнопки).
  • delay — задержка появления и скрытия в миллисекундах: [появление, скрытие].
  • duration — время анимации открытия/закрытия в миллисекундах.
  • theme — настраиваемая тема подсказки (light, dark или кастомная CSS-класс).
  • animation — тип анимации (fade, scale, shift-away и другие).

Пример с интерактивной подсказкой и задержкой:

tippy('#tooltip', {
  content: 'Интерактивная подсказка',
  interactive: true,
  delay: [200, 100],
  theme: 'light',
  animation: 'scale',
});

Использование HTML-контента

Tippy.js позволяет вставлять HTML в подсказку, что делает её более функциональной:

tippy('#htmlButton', {
  content: document.querySelector('#tooltipContent'),
  allowHTML: true,
  interactive: true,
});

Где #tooltipContent — это любой HTML-элемент на странице. Важно использовать allowHTML: true для корректного рендеринга HTML-контента.

Создание типобезопасных оберток

Типобезопасные обертки помогают интегрировать Tippy.js с TypeScript или с проектами, где требуется строгая проверка типов. Основная идея заключается в создании функции-обёртки, которая принимает строго типизированные параметры и возвращает инстанс подсказки с предсказуемым поведением.

Пример типобезопасной обертки:

import tippy, { Instance, Props } from 'tippy.js';

type TooltipOptions = Partial<Props> & {
  selector: string;
  content: string | HTMLElement;
};

export function createTooltip(options: TooltipOptions): Instance[] {
  return tippy(options.selector, {
    content: options.content,
    arrow: true,
    placement: 'top',
    ...options,
  });
}

Эта функция гарантирует, что selector всегда будет строкой, а content — строкой или элементом HTML. Дополнительно можно добавить проверку типов для placement:

type PlacementOptions = 'top' | 'bottom' | 'left' | 'right';

type SafeTooltipOptions = TooltipOptions & {
  placement?: PlacementOptions;
};

Такой подход предотвращает ошибки при передаче некорректных параметров и облегчает автодополнение в редакторах с TypeScript.

Управление жизненным циклом подсказок

Tippy.js предоставляет методы для управления подсказками после их создания:

  • show() — открыть подсказку.
  • hide() — закрыть подсказку.
  • destroy() — удалить подсказку и очистить обработчики.
  • setContent(newContent) — изменить содержимое на лету.

Пример использования с типобезопасной оберткой:

const tooltips = createTooltip({
  selector: '.btn',
  content: 'Нажмите кнопку',
  placement: 'bottom',
});

tooltips.forEach(t => t.show());

Продвинутые возможности: динамическое содержимое и делегирование

Tippy.js поддерживает динамическое обновление содержимого и делегирование событий на родительский элемент, что особенно полезно при работе с большим количеством элементов:

tippy.delegate(document.body, {
  target: '.dynamic-btn',
  content(reference) {
    return reference.getAttribute('data-tooltip') || '';
  },
  interactive: true,
});

В этом примере подсказка создается для любого элемента с классом .dynamic-btn, даже если он добавлен динамически после инициализации Tippy.js.

Настройка анимаций и тем

Tippy.js использует CSS-анимации и темы для кастомизации внешнего вида:

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

.tippy-box[data-animation~='slide'] {
  transition: transform 0.2s ease, opacity 0.2s ease;
}

Использование темы и анимации через опции:

tippy('.themed-btn', {
  content: 'Кастомная тема',
  theme: 'custom',
  animation: 'slide',
});

Интеграция с фреймворками

Tippy.js легко интегрируется с React, Vue и другими современными фреймворками. В React используется библиотека @tippyjs/react, которая обеспечивает компонентный подход и типизацию:

import Tippy from '@tippyjs/react';
import 'tippy.js/dist/tippy.css';

<Tippy content="Подсказка для кнопки">
  <button>Hover me</button>
</Tippy>

Такой подход позволяет создавать полностью типобезопасные и реактивные подсказки, совместимые с современными архитектурами приложений.


Эти методы и практики позволяют строить надёжные, типобезопасные всплывающие элементы, легко поддерживать их и расширять функциональность без потери контроля над типами и поведением подсказок.