Архитектура расширений в Tom Sel ect построена вокруг плагинной модели, в которой базовый экземпляр компонента остаётся минимальным, а вся дополнительная функциональность подключается через модульные расширения. Такой подход позволяет изолировать поведение, избегать монолитности и управлять набором возможностей на уровне конфигурации.
Плагин в контексте Tom Sel ect — это функция, которая получает экземпляр компонента и набор опций, после чего модифицирует поведение, подписывается на события или расширяет API.
Подключение плагинов осуществляется через параметр
plugins при инициализации:
new TomSelect("#select", {
plugins: ["dropdown_input", "remove_button"]
});
В этом случае строковые идентификаторы соответствуют зарегистрированным расширениям внутри Tom Sel ect. При создании экземпляра система проходит по массиву и активирует каждый плагин в порядке объявления.
В стандартной поставке Tom Select присутствует набор готовых расширений, реализующих типовые сценарии:
Каждый из них может быть подключён без дополнительной конфигурации, если сборка включает соответствующие модули.
При использовании модульной сборки подключение плагинов выполняется явно:
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 плагины доступны в глобальном пространстве:
<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) {
// модификация экземпляра
};
}
Логика разделена на два уровня:
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-структуру компонента 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 возможны конфликты:
Стратегии управления:
Плагины в 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Такая структура обеспечивает гибкость расширения без изменения ядра компонента и позволяет комбинировать поведение через независимые модули.