Как отображать информацию о валюте в 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>Currency Information</h1>
      <p>
        Full name: <CurrencyDisplay code="USD" locale={locale} display="name" />
      </p>
      <p>
        Symbol: <CurrencyDisplay code="USD" locale={locale} display="symbol" />
      </p>
      <p>
        Code: <CurrencyDisplay code="USD" locale={locale} display="code" />
      </p>
    </div>
  );
}

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