Множественные языки

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

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

При инициализации компонента передаётся объект настроек, в котором можно определить локализованные строки:

new TomSelect("#select", {
  i18n: {
    no_results: "Ничего не найдено",
    no_items: "Список пуст",
    create_item: "Создать",
    max_items: "Достигнут лимит выбранных элементов",
    loading: "Загрузка..."
  }
});

Каждое поле объекта соответствует конкретному состоянию интерфейса. Такой подход позволяет централизованно управлять текстами без вмешательства в логику работы селекта.

Перечень типовых локализуемых сообщений

В интерфейсе выбора чаще всего переопределяются следующие состояния:

  • отсутствие совпадений при поиске;
  • пустой список элементов;
  • процесс загрузки удалённых данных;
  • достижение максимального количества выбранных значений;
  • создание нового элемента пользователем;
  • подсказки при вводе текста.

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

Использование функций вместо статических строк

Вместо фиксированных строк допускается использование функций, что позволяет учитывать контекст, например количество выбранных элементов или введённый запрос:

new TomSelect("#select", {
  i18n: {
    max_items: (max) => `Можно выбрать не более ${max} элементов`,
    no_results: (query) => `По запросу "${query}" ничего не найдено`
  }
});

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

Переключение языка во время выполнения

В сценариях, где интерфейс должен поддерживать смену языка без перезагрузки страницы, используется обновление конфигурации экземпляра и перерисовка текстовых элементов:

const select = new TomSelect("#select", {
  i18n: {
    no_results: "Ничего не найдено",
    loading: "Загрузка..."
  }
});

function setEnglish() {
  select.settings.i18n = {
    no_results: "No results found",
    loading: "Loading..."
  };

  select.refreshOptions(false);
}

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

Интеграция с внешними системами интернационализации

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

function t(key) {
  const dictionary = {
    ru: {
      no_results: "Ничего не найдено",
      loading: "Загрузка..."
    },
    en: {
      no_results: "No results found",
      loading: "Loading..."
    }
  };

  return dictionary[currentLocale][key];
}

new TomSelect("#select", {
  i18n: {
    no_results: () => t("no_results"),
    loading: () => t("loading")
  }
});

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

Обработка асинхронных данных и языковые сообщения

При использовании удалённых источников данных интерфейс часто находится в состоянии загрузки или ожидания ответа сервера. В таких случаях особенно важно корректно локализовать промежуточные состояния:

new TomSelect("#select", {
  load: function(query, callback) {
    fetch(`/api/search?q=${query}`)
      .then(res => res.json())
      .then(data => callback(data))
      .catch(() => {
        callback();
      });
  },
  i18n: {
    loading: "Идёт загрузка данных...",
    no_results: "Совпадений не найдено"
  }
});

Сообщения становятся частью асинхронного цикла, отражая состояние запроса в интерфейсе.

Локализация в условиях динамического создания элементов

Если компонент позволяет пользователю создавать новые значения, текст кнопки или подсказки также подлежат переводу:

new TomSelect("#select", {
  create: true,
  createText: function(input) {
    return `Добавить "${input}"`;
  }
});

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

Поддержка направленного текста и региональных особенностей

Мультиязычность включает не только перевод строк, но и особенности отображения. Для языков с направлением письма справа налево учитывается CSS-уровень и контейнерная настройка:

[dir="rtl"] .ts-control {
  text-align: right;
}

Сам компонент не изменяет направление автоматически, поэтому управление осуществляется на уровне приложения.

Архитектурные подходы к мультиязычности

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

function createSelect(locale) {
  return new TomSelect("#select", {
    i18n: getLocaleStrings(locale)
  });
}

function getLocaleStrings(locale) {
  const locales = {
    ru: {
      no_results: "Ничего не найдено",
      loading: "Загрузка"
    },
    en: {
      no_results: "No results found",
      loading: "Loading"
    }
  };

  return locales[locale];
}

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

Переиспользование языковых пакетов

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

const tomSelectI18n = {
  ru: {
    no_results: "Ничего не найдено",
    no_items: "Нет элементов",
    loading: "Загрузка"
  },
  en: {
    no_results: "No results found",
    no_items: "No items",
    loading: "Loading"
  }
};

Далее каждый экземпляр компонента получает ссылки на единый источник строк, что снижает вероятность рассинхронизации интерфейса.

Согласование локализации с состоянием формы

В формах с несколькими селектами важно, чтобы язык компонентов совпадал с языком всей формы. При смене языка формы выполняется синхронное обновление всех экземпляров:

const selects = [];

function initSelect(selector) {
  const instance = new TomSelect(selector, {
    i18n: tomSelectI18n[currentLocale]
  });

  selects.push(instance);
}

function updateLanguage(locale) {
  currentLocale = locale;

  selects.forEach(s => {
    s.settings.i18n = tomSelectI18n[locale];
    s.refreshOptions(false);
  });
}

Такая схема обеспечивает единообразие текстов во всех элементах интерфейса без пересоздания компонентов.

Обработка пользовательских сценариев ввода

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

new TomSelect("#select", {
  i18n: {
    no_results: (query) => {
      if (!query) return "Пустой запрос";
      return `По запросу "${query}" ничего не найдено`;
    }
  }
});

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