Типизация плагинов

Tippy.js предоставляет мощную систему расширений через плагины, которые позволяют добавлять кастомное поведение к тултипам. Типизация плагинов является ключевым аспектом для обеспечения корректной интеграции, безопасной работы с API и автодополнения в редакторах кода.

В Tippy.js каждый плагин представляет собой объект с набором обязательных и опциональных методов. Основные поля плагина:

  • name – уникальный идентификатор плагина, строка. Используется для регистрации и дебага.
  • defaultValue – значение по умолчанию для опций плагина. Может быть любого типа, но чаще всего объект.
  • fn – функция инициализации плагина, которая получает объект с текущими опциями тултипа и ссылку на его экземпляр.

Пример типизированного плагина на TypeScript:

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

interface MyPluginOptions {
  highlightColor?: string;
}

const myPlugin: Plugin<MyPluginOptions> = {
  name: 'highlight',
  defaultValue: { highlightColor: 'yellow' },
  fn(instance: Instance, options: MyPluginOptions) {
    return {
      onShow() {
        if (options.highlightColor) {
          instance.popper.style.backgroundColor = options.highlightColor;
        }
      }
    };
  }
};

Здесь ключевой момент – указание интерфейса опций плагина, что обеспечивает автодополнение и проверку типов при использовании.

Интерфейс Plugin и его методы

Tippy.js экспортирует интерфейс Plugin<T>, где T – тип объекта опций. Основные свойства и методы:

  • name: string – обязательное поле для идентификации плагина.

  • defaultValue: T – объект с дефолтными значениями опций.

  • fn(instance: Instance, options: T): Partial – функция инициализации. Возвращаемый объект может содержать хуки жизненного цикла тултипа:

    • onCreate – вызывается при создании экземпляра.
    • onShow – вызывается перед показом тултипа.
    • onHide – вызывается перед скрытием.
    • onMount – вызывается при монтировании DOM.
    • onDestroy – вызывается при уничтожении экземпляра.

Пример использования нескольких хуков в плагине:

const loggingPlugin: Plugin<{ logLevel: 'info' | 'warn' | 'error' }> = {
  name: 'logger',
  defaultValue: { logLevel: 'info' },
  fn(instance, options) {
    return {
      onShow() {
        console[options.logLevel](`Тултип ${instance.id} показывается`);
      },
      onHide() {
        console[options.logLevel](`Тултип ${instance.id} скрыт`);
      }
    };
  }
};

Типизация опций плагина

Опции плагина могут содержать как примитивные типы, так и сложные структуры. Основное правило: все опции должны быть строго типизированы через интерфейс.

Пример сложной типизации:

interface TooltipEnhancerOptions {
  delay?: number | [number, number];
  animate?: boolean;
  styles?: {
    color?: string;
    fontSize?: string;
  };
}

const enhancerPlugin: Plugin<TooltipEnhancerOptions> = {
  name: 'enhancer',
  defaultValue: { delay: 0, animate: true, styles: {} },
  fn(instance, options) {
    return {
      onShow() {
        if (options.styles?.color) {
          instance.popper.style.color = options.styles.color;
        }
      }
    };
  }
};

В этом примере типизация массива [number, number] для задержки обеспечивает строгую проверку формата опции.

Интеграция плагинов с экземплярами Tippy

При создании тултипа плагин подключается через поле plugins в конфигурации. Типы автоматически проверяются TypeScript:

tippy('#button', {
  content: 'Подсказка',
  plugins: [myPlugin, loggingPlugin],
  highlightColor: 'lightblue',  // типизированная опция для myPlugin
  logLevel: 'warn'               // типизированная опция для loggingPlugin
});

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

Рекомендации по типизации

  • Всегда указывать интерфейс для опций плагина.
  • Использовать строгие типы (string, number, boolean, кортежи, перечисления).
  • Определять дефолтные значения через defaultValue для корректного срабатывания всех хуков.
  • Возвращаемый объект из fn должен содержать только те хуки, которые реально используются.

Типизация плагинов позволяет создавать расширяемую и безопасную архитектуру тултипов, облегчает отладку и поддерживает автодополнение в IDE.