Форматирование в зависимости от локали

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

Tippy.js не предоставляет встроенной системы интернационализации, однако её легко интегрировать с JavaScript-функциями и библиотеками для локализации, такими как Intl, i18next или dayjs. Основной подход заключается в динамическом формировании контента тултипа на основе текущей локали.


Динамическое изменение текста в зависимости от локали

import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';

// Пример использования Intl для форматирования дат
const locale = navigator.language || 'en-US';
const formattedDate = new Intl.DateTimeFormat(locale, {
  year: 'numeric',
  month: 'long',
  day: 'numeric'
}).format(new Date());

tippy('#date-tooltip', {
  content: `Сегодняшняя дата: ${formattedDate}`,
  placement: 'top',
  theme: 'light'
});

В этом примере используется стандартный объект Intl.DateTimeFormat, который автоматически подбирает формат даты под текущую локаль. Аналогичным образом можно использовать Intl.NumberFormat для чисел и валют:

const price = 1234.56;
const formattedPrice = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'USD'
}).format(price);

tippy('#price-tooltip', {
  content: `Цена: ${formattedPrice}`,
  placement: 'right',
  theme: 'light-border'
});

Использование i18next с Tippy.js

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

import i18next from 'i18next';
import tippy from 'tippy.js';

i18next.init({
  lng: 'ru',
  resources: {
    ru: {
      translation: {
        greeting: "Привет, {{name}}!",
        tooltipInfo: "Дополнительная информация"
      }
    },
    en: {
      translation: {
        greeting: "Hello, {{name}}!",
        tooltipInfo: "Additional information"
      }
    }
  }
});

tippy('#info-tooltip', {
  content: i18next.t('tooltipInfo'),
  placement: 'bottom',
  theme: 'material'
});

// Динамическое обновление локали
document.querySelector('#change-lang').addEventListener('click', () => {
  i18next.changeLanguage('en').then(() => {
    const instance = tippy('#info-tooltip')[0];
    instance.setContent(i18next.t('tooltipInfo'));
  });
});

Особенности:

  • i18next позволяет легко заменять тексты тултипов без необходимости пересоздавать экземпляры Tippy.js.
  • Метод setContent() позволяет обновлять содержимое на лету при смене локали.

Форматирование чисел и валют

Tippy.js может работать с любым динамически вычисленным контентом, включая числа с разделителями тысяч, проценты, валюты.

const number = 9876543.21;

const formattedNumber = new Intl.NumberFormat(locale, {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
}).format(number);

tippy('#number-tooltip', {
  content: `Сумма: ${formattedNumber}`,
  placement: 'left',
  theme: 'dark'
});

Использование Intl.NumberFormat гарантирует корректное отображение:

  • Разделителей тысяч
  • Знаков десятичных долей
  • Символов валюты (при указании style: 'currency' и currency: 'EUR' или другой валюты)

Многострочные и интерполированные тултипы

Локализация часто требует поддержки многострочного текста и интерполяции переменных.

const userName = "Иван";
const tooltipContent = `
  Привет, ${userName}!
  Сегодня: ${new Intl.DateTimeFormat(locale).format(new Date())}
  Счет: ${new Intl.NumberFormat(locale, { style: 'currency', currency: 'RUB' }).format(5000)}
`;

tippy('#user-tooltip', {
  content: tooltipContent,
  allowHTML: true,
  placement: 'top-start',
  theme: 'light-border'
});

Особенности:

  • allowHTML: true позволяет использовать переносы строк <br> или другие HTML-элементы.
  • Интерполяция переменных позволяет отображать динамический контент без изменения кода тултипа.

Смена локали в реальном времени

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

function updateLocale(locale) {
  const tooltipElements = document.querySelectorAll('[data-tooltip-key]');
  tooltipElements.forEach(el => {
    const key = el.dataset.tooltipKey;
    const instance = tippy(el)[0];
    instance.setContent(i18next.t(key, { lng: locale }));
  });
}

В этом подходе:

  • Все тултипы привязаны к ключам перевода (data-tooltip-key).
  • Смена локали вызывает обновление всех экземпляров Tippy.js через setContent().
  • Можно комбинировать с форматированием дат и чисел через i18next или Intl.

Настройка позиционирования для разных языков

Некоторые языки требуют изменения позиции тултипов, например, при локалях с правой-to-left текстом (ar, he). Tippy.js позволяет динамически менять placement:

const isRTL = ['ar', 'he'].includes(locale);

tippy('#rtl-tooltip', {
  content: "Текст для RTL",
  placement: isRTL ? 'left' : 'right',
  theme: 'light'
});

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


Интеграция с date-fns или dayjs

Для более сложного форматирования дат можно использовать date-fns или dayjs с локальными пакетами:

import dayjs from 'dayjs';
import 'dayjs/locale/ru';

dayjs.locale(locale);
const formattedDate = dayjs().format('D MMMM YYYY');

tippy('#date-fns-tooltip', {
  content: `Сегодня: ${formattedDate}`,
  placement: 'bottom',
  theme: 'material'
});

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


Tippy.js, в сочетании с возможностями JavaScript по локализации (Intl, i18next, dayjs), позволяет строить гибкие, мультиязычные и корректно форматированные интерфейсы, где тултипы адаптируются под локаль пользователя, поддерживают динамические данные и интегрируются с любыми системами перевода.