В Pikaday локализация строится вокруг объекта i18n,
который передаётся при инициализации календаря. Он содержит все
текстовые элементы интерфейса: названия месяцев, дней недели, подписи
кнопок навигации и вспомогательные строки. Архитектура библиотеки
предполагает, что язык задаётся на уровне конфигурации, а не через
глобальные настройки, что делает возможным гибкое переключение без
перезагрузки страницы, но требует аккуратного управления состоянием
экземпляра календаря.
Ключевая особенность заключается в том, что Pikaday не привязан к
конкретному языковому пакету — разработчик сам формирует набор переводов
и передаёт его в i18n. Это означает, что динамическая смена
языка реализуется либо через обновление существующего экземпляра, либо
через пересоздание календаря с новой конфигурацией.
Объект локализации в Pikaday обычно включает следующие поля:
previousMonthnextMonthmonthsweekdaysweekdaysShortweekdaysMinКаждое из этих полей отвечает за отдельную часть интерфейса
календаря. Например, массив months определяет отображение
названий месяцев в заголовке, а weekdaysMin используется в
шапке сетки дней.
Пример базовой локализации:
const ruLocale = {
previousMonth: 'Предыдущий месяц',
nextMonth: 'Следующий месяц',
months: [
'Январь', 'Февраль', 'Март', 'Апрель',
'Май', 'Июнь', 'Июль', 'Август',
'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
],
weekdays: [
'Воскресенье', 'Понедельник', 'Вторник',
'Среда', 'Четверг', 'Пятница', 'Суббота'
],
weekdaysShort: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
weekdaysMin: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
};
Такая структура полностью определяет текстовую составляющую календаря, не затрагивая его поведение.
При стандартной инициализации Pikaday язык фиксируется:
const picker = new Pikaday({
field: document.getElementById('date'),
i18n: ruLocale
});
После создания экземпляра календаря библиотека использует переданный
объект как источник всех текстовых значений. Изменение переменной
ruLocale после инициализации не влияет на уже созданный
календарь, поскольку данные копируются или кэшируются внутри
экземпляра.
Это создаёт необходимость в отдельной стратегии обновления языка.
Существует несколько рабочих моделей переключения локализации, каждая из которых подходит под разные архитектуры приложения.
Наиболее надёжный и предсказуемый способ — уничтожение текущего экземпляра и создание нового с обновлённой локализацией.
let picker = new Pikaday({
field: document.getElementById('date'),
i18n: ruLocale
});
function setLanguage(locale) {
const selectedLocale = locale === 'en' ? enLocale : ruLocale;
picker.destroy();
picker = new Pikaday({
field: document.getElementById('date'),
i18n: selectedLocale
});
}
Такой подход гарантирует полную перерисовку интерфейса и отсутствие побочных эффектов, связанных с внутренним состоянием календаря.
Pikaday хранит конфигурацию в объекте экземпляра, обычно в свойстве
_o. Хотя это внутренний API, он часто используется для
динамических обновлений без пересоздания.
function setLanguage(locale) {
picker._o.i18n = locale;
picker.draw(true);
}
Метод draw(true) заставляет календарь полностью
перерисовать текущий месяц, применяя обновлённые строки интерфейса.
Этот способ быстрее пересоздания, но зависит от внутренней реализации библиотеки и может быть чувствителен к изменениям версии.
При наличии нескольких языков удобно вынести локализации в отдельный словарь:
const locales = {
ru: ruLocale,
en: enLocale,
de: deLocale
};
И управлять переключением через единый интерфейс:
function setLanguage(lang) {
picker.destroy();
picker = new Pikaday({
field: document.getElementById('date'),
i18n: locales[lang]
});
}
Такая архитектура упрощает масштабирование и добавление новых языков без изменения логики календаря.
При пересоздании экземпляра возникает задача сохранения выбранной
даты. Pikaday позволяет задать начальное значение через
setDate, поэтому состояние можно восстановить:
const currentDate = picker.getDate();
picker.destroy();
picker = new Pikaday({
field: document.getElementById('date'),
i18n: locales[lang]
});
picker.setDate(currentDate);
Это обеспечивает визуальную непрерывность при смене языка.
В современных приложениях переключение языка часто связано с состоянием UI-фреймворка. В таком случае Pikaday выступает как контролируемый компонент.
Логика обычно строится вокруг подписки на изменение языка:
function updateCalendarLanguage(lang) {
const locale = locales[lang];
picker._o.i18n = locale;
picker.draw(true);
}
При этом важно учитывать, что перерисовка влияет только на текущий открытый месяц. Для полного обновления интерфейса иногда требуется повторное открытие календаря.
Хотя i18n отвечает за текстовую часть, формат даты
задаётся отдельно через параметр format. При смене языка
часто требуется синхронное обновление формата.
const formats = {
ru: 'DD.MM.YYYY',
en: 'MM/DD/YYYY'
};
function setLanguage(lang) {
picker.destroy();
picker = new Pikaday({
field: document.getElementById('date'),
i18n: locales[lang],
format: formats[lang]
});
}
Игнорирование формата приводит к несоответствию локали и отображения даты, особенно в пользовательских интерфейсах с вводом.
При использовании нескольких экземпляров Pikaday на одной странице динамическая смена языка требует централизованного управления. Обычно создаётся единый модуль локализации:
class CalendarManager {
constructor() {
this.instances = [];
this.currentLang = 'ru';
}
register(picker) {
this.instances.push(picker);
}
setLanguage(lang) {
this.currentLang = lang;
this.instances.forEach(picker => {
picker._o.i18n = locales[lang];
picker.draw(true);
});
}
}
Такой подход позволяет синхронно обновлять все календари без их пересоздания.
При смене языка во время открытого интерфейса Pikaday перерисовывает DOM без закрытия попапа. Однако визуальное обновление может быть частичным в зависимости от браузера и текущего состояния отрисовки.
В некоторых случаях требуется принудительное закрытие и повторное открытие:
picker.hide();
picker.show();
Это обеспечивает полное обновление всех элементов интерфейса.
Динамическая смена языка в Pikaday не является полноценным реактивным
механизмом. Библиотека не имеет встроенной системы наблюдения за
изменением i18n, поэтому любое обновление требует ручного
вызова перерисовки или пересоздания.
Внутренние кэши строк и массивов могут сохраняться между обновлениями, если не используется полная перерисовка экземпляра. Это делает пересоздание более стабильным решением в сложных интерфейсах.
Выбор метода зависит от требований к производительности и стабильности:
_o.i18n применяется в высокочастотных
переключениях языка