Как отображать информацию о валюте в TanStack Start v1

Отображение кодов валют, названий и символов

Проблема

Приложения часто нуждаются в отображении информации о валюте без форматирования цены. Например, селектор валют может перечислять доступные валюты, статья о валютных курсах может ссылаться на конкретные валюты по их символам, а финансовая панель может показывать коды валют. Однако у каждого из этих представлений есть свои ограничения. ISO-коды, такие как "USD", точны, но непонятны для нетехнических пользователей. Полные названия, такие как "доллар США", понятны, но требуют перевода для международной аудитории. Символы, такие как "$", знакомы, но неоднозначны — один и тот же символ используется для обозначения долларов США, Канады и Австралии. Неправильный выбор формата для контекста снижает ясность и может запутать пользователей.

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

Решение

Используйте встроенные API интернационализации браузера для отображения информации о валюте в формате, соответствующем как локали пользователя, так и контексту. API Intl.DisplayNames предоставляет локализованные полные названия валют, а Intl.NumberFormat с опцией currencyDisplay может извлекать символы или коды валют. Выбирая подходящий API и опцию формата в зависимости от контекста, вы обеспечиваете, что ссылки на валюты будут как понятными, так и правильно локализованными, без необходимости поддерживать данные перевода.

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

Шаги

1. Создайте хелпер для получения локализованных названий валют

API Intl.DisplayNames с параметром type: "currency" возвращает локализованные полные названия валют для любого кода валюты ISO 4217.

export function getCurrencyName(currencyCode: string, locale: string): string {
  const displayNames = new Intl.DisplayNames([locale], { type: "currency" });
  return displayNames.of(currencyCode) || currencyCode;
}

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

2. Создайте хелпер для извлечения символов валют

Опция currencyDisplay в Intl.NumberFormat управляет тем, как отображается валюта, с возможными значениями "code", "symbol", "narrowSymbol" и "name".

export function getCurrencySymbol(
  currencyCode: string,
  locale: string,
  narrow: boolean = false,
): string {
  const formatter = new Intl.NumberFormat(locale, {
    style: "currency",
    currency: currencyCode,
    currencyDisplay: narrow ? "narrowSymbol" : "symbol",
  });

  const parts = formatter.formatToParts(0);
  const currencyPart = parts.find((part) => part.type === "currency");
  return currencyPart?.value || currencyCode;
}

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

3. Создайте компонент для отображения информации о валюте

Создайте гибкий компонент, который может отображать информацию о валюте в любом формате на основе свойства display.

interface CurrencyDisplayProps {
  code: string;
  locale: string;
  display: "name" | "symbol" | "narrowSymbol" | "code";
}

export function CurrencyDisplay({
  code,
  locale,
  display,
}: CurrencyDisplayProps) {
  let content: string;

  if (display === "name") {
    content = getCurrencyName(code, locale);
  } else if (display === "code") {
    content = code.toUpperCase();
  } else {
    content = getCurrencySymbol(code, locale, display === "narrowSymbol");
  }

  return <span>{content}</span>;
}

Этот компонент централизует логику отображения валюты и упрощает переключение форматов. Используйте "name" для выпадающих списков и пояснительного текста, "symbol" или "narrowSymbol" для компактного отображения и "code", когда требуется точность.

4. Используйте компонент в маршруте TanStack Start

Импортируйте и используйте компонент в любом маршруте, передавая локаль пользователя из вашего i18n-контекста или загрузчика маршрута.

import { createFileRoute } from "@tanstack/react-router";
import { CurrencyDisplay } from "~/components/CurrencyDisplay";

export const Route = createFileRoute("/currencies")({
  component: CurrenciesPage,
});

function CurrenciesPage() {
  const locale = "en-US";

  return (
    <div>
      <h1>Информация о валюте</h1>
      <p>
        Полное название: <CurrencyDisplay code="USD" locale={locale} display="name" />
      </p>
      <p>
        Символ: <CurrencyDisplay code="USD" locale={locale} display="symbol" />
      </p>
      <p>
        Код: <CurrencyDisplay code="USD" locale={locale} display="code" />
      </p>
    </div>
  );
}

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