Подключение плагинов

Архитектура расширений в Tom Sel ect построена вокруг плагинной модели, в которой базовый экземпляр компонента остаётся минимальным, а вся дополнительная функциональность подключается через модульные расширения. Такой подход позволяет изолировать поведение, избегать монолитности и управлять набором возможностей на уровне конфигурации.

Плагин в контексте Tom Sel ect — это функция, которая получает экземпляр компонента и набор опций, после чего модифицирует поведение, подписывается на события или расширяет API.


Базовый механизм регистрации плагинов

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

new TomSelect("#select", {
  plugins: ["dropdown_input", "remove_button"]
});

В этом случае строковые идентификаторы соответствуют зарегистрированным расширениям внутри Tom Sel ect. При создании экземпляра система проходит по массиву и активирует каждый плагин в порядке объявления.


Встроенные плагины и их загрузка

В стандартной поставке Tom Select присутствует набор готовых расширений, реализующих типовые сценарии:

  • управление выпадающим списком
  • кнопки удаления выбранных значений
  • работа с тегами
  • автоматический ввод в dropdown
  • визуальные улучшения интерфейса

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


Подключение через ES Modules

При использовании модульной сборки подключение плагинов выполняется явно:

import TomSelect fr om "tom-select";
import dropdown_input fr om "tom-select/plugins/dropdown_input";
import remove_button fr om "tom-select/plugins/remove_button";

new TomSelect("#select", {
  plugins: {
    dropdown_input,
    remove_button
  }
});

В этом варианте Tom Select получает не строковые идентификаторы, а ссылки на функции-плагины, что позволяет tree-shaking и более строгий контроль зависимостей.


CDN-подключение и глобальная регистрация

При подключении через CDN плагины доступны в глобальном пространстве:

<script src="tom-select.min.js"></script>
<script src="plugins/remove_button.min.js"></script>

<script>
  new TomSelect("#select", {
    plugins: ["remove_button"]
  });
</script>

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


Сигнатура плагина

Каждый плагин в Tom Select представляет собой функцию следующего вида:

function pluginName(userOptions) {
  return function (tomSelectInstance) {
    // модификация экземпляра
  };
}

Логика разделена на два уровня:

  1. Внешняя функция принимает конфигурацию плагина
  2. Внутренняя функция получает экземпляр и изменяет его поведение

Пример простого пользовательского плагина

function highlightActive() {
  return function (ts) {
    ts.on("item_add", function () {
      ts.wrapper.classList.add("has-active-item");
    });

    ts.on("item_remove", function () {
      if (!ts.items.length) {
        ts.wrapper.classList.remove("has-active-item");
      }
    });
  };
}

new TomSelect("#select", {
  plugins: {
    highlightActive
  }
});

В этом примере плагин подписывается на события экземпляра Tom Select и управляет состоянием DOM-контейнера.


Регистрация плагинов в рантайме

Tom Select позволяет регистрировать плагины глобально через API:

TomSelect.define("highlight_active", function (options) {
  return function (ts) {
    ts.on("item_add", () => {
      ts.wrapper.classList.add("active");
    });
  };
});

После регистрации плагин становится доступен как строковый идентификатор:

new TomSelect("#select", {
  plugins: ["highlight_active"]
});

Порядок инициализации плагинов

Плагины в Tom Select инициализируются строго последовательно. Это важно при наличии зависимостей между расширениями.

Особенности порядка:

  • плагины выполняются в порядке массива plugins
  • каждый следующий плагин получает уже модифицированный экземпляр
  • изменения могут накапливаться или перезаписываться

Взаимодействие плагинов с жизненным циклом

Плагины внутри Tom Select могут подключаться к основным этапам жизненного цикла:

  • инициализация (initialize)
  • создание элементов интерфейса
  • обработка ввода
  • изменение состояния выбора
  • уничтожение экземпляра (destroy)

Пример:

function lifecyclePlugin() {
  return function (ts) {
    ts.on("initialize", () => {
      console.log("init");
    });

    ts.on("destroy", () => {
      console.log("cleanup");
    });
  };
}

Изоляция состояния плагинов

Каждый плагин в Tom Select должен избегать глобального состояния. Вместо этого используется замыкание:

function counterPlugin() {
  let counter = 0;

  return function (ts) {
    ts.on("item_add", () => {
      counter++;
    });
  };
}

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


Удаление плагинов

В Tom Select нет универсального динамического отключения плагинов после инициализации, поэтому управление обычно строится через:

  • уничтожение экземпляра (destroy)
  • повторную инициализацию с другим набором плагинов
const ts = new TomSelect("#select", {
  plugins: ["remove_button"]
});

ts.destroy();

new TomSelect("#select", {
  plugins: []
});

Плагины и расширение DOM-структуры

Плагины часто модифицируют DOM-структуру компонента Tom Select:

  • добавляют кнопки
  • вставляют обёртки
  • меняют классы
  • изменяют шаблоны отображения

Пример добавления элемента:

function badgePlugin() {
  return function (ts) {
    const badge = document.createElement("span");
    badge.className = "ts-badge";

    ts.wrapper.appendChild(badge);

    ts.on("item_add", () => {
      badge.textContent = ts.items.length;
    });
  };
}

Конфликты плагинов и стратегия их разрешения

При комбинировании нескольких расширений Tom Select возможны конфликты:

  • перезапись DOM-узлов
  • конкуренция за события
  • дублирование логики

Стратегии управления:

  • строгий порядок подключения
  • разделение ответственности плагинов
  • минимизация прямых DOM-манипуляций
  • использование событий вместо прямых изменений состояния

Расширение API через плагины

Плагины в Tom Select могут расширять публичный API экземпляра:

function apiPlugin() {
  return function (ts) {
    ts.clearAll = function () {
      ts.clear();
      ts.blur();
    };
  };
}

После подключения метод становится доступным на экземпляре:

const ts = new TomSelect("#select", {
  plugins: { apiPlugin }
});

ts.clearAll();

Итоговая модель подключения

Механика подключения плагинов в Tom Select строится на трёх уровнях:

  • декларативное подключение через конфигурацию plugins
  • функциональная модель плагина как фабрики
  • событийная интеграция с жизненным циклом экземпляра

Такая структура обеспечивает гибкость расширения без изменения ядра компонента и позволяет комбинировать поведение через независимые модули.