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

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

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

Основные поля, отвечающие за язык интерфейса, сосредоточены в объекте настроек:

  • placeholder
  • searchText
  • searchingText
  • noResultsText
  • noChoicesText
  • loadingText

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

Пример инициализации с русской локализацией:

new SlimSelect({
  select: '#select',
  settings: {
    placeholderText: 'Выберите значение',
    searchText: 'Поиск...',
    searchingText: 'Идёт поиск...',
    noResultsText: 'Ничего не найдено',
    noChoicesText: 'Нет доступных вариантов',
    loadingText: 'Загрузка...'
  }
});

Каждое текстовое поле связано с определённым состоянием интерфейса. Например, searchText отображается внутри строки поиска, когда поле пустое, а noResultsText появляется после фильтрации, если совпадений нет.

Структура языковых конфигураций

При работе с несколькими языками удобно выносить все переводы в отдельные структуры. Это позволяет избежать дублирования кода и централизовать управление локализацией.

const translations = {
  ru: {
    placeholderText: 'Выберите значение',
    searchText: 'Поиск...',
    searchingText: 'Идёт поиск...',
    noResultsText: 'Ничего не найдено',
    noChoicesText: 'Нет доступных вариантов',
    loadingText: 'Загрузка...'
  },
  en: {
    placeholderText: 'Select value',
    searchText: 'Search...',
    searchingText: 'Searching...',
    noResultsText: 'No results found',
    noChoicesText: 'No options available',
    loadingText: 'Loading...'
  },
  kk: {
    placeholderText: 'Мәнді таңдаңыз',
    searchText: 'Іздеу...',
    searchingText: 'Ізделуде...',
    noResultsText: 'Ештеңе табылмады',
    noChoicesText: 'Опциялар жоқ',
    loadingText: 'Жүктелуде...'
  }
};

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

Динамическое переключение языка

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

Стандартный подход заключается в уничтожении текущего экземпляра и создании нового с другим набором параметров:

let currentLang = 'ru';
let selectInstance = null;

function initSelect(lang) {
  if (selectInstance) {
    selectInstance.destroy();
  }

  selectInstance = new SlimSelect({
    select: '#select',
    settings: translations[lang]
  });
}

initSelect(currentLang);

function switchLanguage(lang) {
  currentLang = lang;
  initSelect(lang);
}

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

Локализация в асинхронных данных

При использовании удалённых источников данных локализация затрагивает не только UI-тексты, но и содержимое опций. Серверные данные часто приходят на одном языке, что требует дополнительной обработки на клиентской стороне.

Типичный сценарий включает трансформацию массива данных перед передачей в Slim Select:

function mapOptions(data, lang) {
  return data.map(item => ({
    text: item.translations[lang],
    value: item.id
  }));
}

Структура данных при этом может выглядеть следующим образом:

const data = [
  {
    id: 1,
    translations: {
      ru: 'Москва',
      en: 'Moscow',
      kk: 'Мәскеу'
    }
  }
];

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

Интеграция с системами i18n

При использовании сторонних библиотек интернационализации, таких как общие i18n-движки, Slim Select выступает как потребитель готовых строк перевода. В этом случае конфигурация становится отражением состояния глобального языкового хранилища.

Пример интеграции с условной функцией t:

function createSettings() {
  return {
    placeholderText: t('select.placeholder'),
    searchText: t('select.search'),
    searchingText: t('select.searching'),
    noResultsText: t('select.noResults'),
    noChoicesText: t('select.noChoices'),
    loadingText: t('select.loading')
  };
}

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

i18n.onChange(() => {
  initSelect(i18n.getCurrentLanguage());
});

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

Особенности множественных экземпляров

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

Корректная архитектура предполагает единый фабричный метод:

function createSlimSelect(selector, lang) {
  return new SlimSelect({
    select: selector,
    settings: translations[lang]
  });
}

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

Контекстные языковые изменения

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

В этом случае каждая инстанция хранит собственное состояние языка:

class LocalizedSelect {
  constructor(selector, lang) {
    this.lang = lang;
    this.instance = new SlimSelect({
      select: selector,
      settings: translations[lang]
    });
  }

  setLanguage(lang) {
    this.lang = lang;
    this.instance.destroy();
    this.instance = new SlimSelect({
      select: '#select',
      settings: translations[lang]
    });
  }
}

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

Обработка направлений текста

При добавлении языков с различным направлением письма, например RTL-языков, Slim Select требует дополнительной стилизации через CSS. Логика компонента не управляет направлением текста автоматически, поэтому ответственность за это лежит на разработчике.

Пример адаптации:

[dir="rtl"] .ss-main {
  text-align: right;
}

[dir="rtl"] .ss-search {
  direction: rtl;
}

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

document.documentElement.setAttribute('dir', 'rtl');

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

Работа с плейсхолдерами и пустыми значениями

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

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

settings: {
  placeholderText: t('select.placeholder'),
  allowDeselect: true
}

При отсутствии выбора компонент отображает локализованный текст, заданный через placeholderText, что обеспечивает единообразие интерфейса.

Итоговая архитектурная модель локализации

Модель поддержки нескольких языков в Slim Select строится на трёх уровнях: конфигурационные тексты, локализация данных и внешняя система управления переводами. Отсутствие встроенного i18n-слоя делает компонент максимально гибким, но переносит ответственность за синхронизацию языков на уровень приложения.

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