UNPKG

react-native-localize

Version:

A toolbox for your React Native app localization.

153 lines (121 loc) 3.89 kB
import { CURRENCIES, USES_FAHRENHEIT, USES_IMPERIAL, USES_RTL_LAYOUT, } from "./constants"; import type { Calendar, Locale, NumberFormatSettings, TemperatureUnit, } from "./types"; function ensureCountryCode(countryCode: string): string { return countryCode === "419" ? "UN" : countryCode.toUpperCase(); } function splitLanguageTag(languageTag: string): { languageCode: string; countryCode?: string; } { const [languageCode = "en", countryCode] = languageTag.split("-"); return { languageCode, countryCode }; } function convertLanguageTagToLocale( languageTag: string, countryCodeFallback: string, ): Locale { let { languageCode, countryCode } = splitLanguageTag(languageTag); languageCode = languageCode.toLowerCase(); countryCode = ensureCountryCode(countryCode || countryCodeFallback); return { languageCode, countryCode, languageTag: `${languageCode}-${countryCode}`, isRTL: USES_RTL_LAYOUT.includes(languageCode), }; } function getCurrentLocale(): Locale { return convertLanguageTagToLocale(navigator.language, getCountry()); } export function getCalendar(): Calendar { return "gregorian"; } export function getCountry(): string { const { languages = [navigator.language] } = navigator; for (let i = 0; i < languages.length; i++) { const language = languages[i]; if (!language) { continue; } const { countryCode } = splitLanguageTag(language); if (countryCode) { return ensureCountryCode(countryCode); } } return "US"; } export function getCurrencies(): string[] { const { languages = [navigator.language] } = navigator; const currencies: string[] = []; languages.forEach((language) => { const { countryCode } = splitLanguageTag(language); if (countryCode) { const currency = CURRENCIES[ensureCountryCode(countryCode)]; if (currency && currencies.indexOf(currency) === -1) { currencies.push(currency); } } }); if (currencies.length === 0) { currencies.push("USD"); } return currencies; } export function getLocales(): Locale[] { const { languages = [navigator.language] } = navigator; const countryCode = getCountry(); const cache: string[] = []; const locales: Locale[] = []; languages.forEach((language) => { const locale = convertLanguageTagToLocale(language, countryCode); if (cache.indexOf(locale.languageTag) === -1) { locales.push(locale); cache.push(locale.languageTag); } }); return locales; } export function getNumberFormatSettings(): NumberFormatSettings { const { languageTag } = getCurrentLocale(); const formatter = new Intl.NumberFormat(languageTag); const separators = formatter.format(1000000.1).replace(/\d/g, ""); return { decimalSeparator: separators[separators.length - 1] || ".", groupingSeparator: separators[0] || ",", }; } export function getTemperatureUnit(): TemperatureUnit { return USES_FAHRENHEIT.includes(getCountry()) ? "fahrenheit" : "celsius"; } export function getTimeZone(): string { const { languageTag } = getCurrentLocale(); const formatter = new Intl.DateTimeFormat(languageTag, { hour: "numeric" }); return formatter.resolvedOptions().timeZone || "Etc/UTC"; } export function uses24HourClock(): boolean { const { languageTag } = getCurrentLocale(); const formatter = new Intl.DateTimeFormat(languageTag, { hour: "numeric" }); return !formatter.format(new Date(2000, 0, 1, 20)).match(/am|pm/i); } export function usesMetricSystem(): boolean { return !USES_IMPERIAL.includes(getCountry()); } export function usesAutoDateAndTime(): boolean | undefined { return; } export function usesAutoTimeZone(): boolean | undefined { return; } export async function openAppLanguageSettings(): Promise<void> { throw new Error("openAppLanguageSettings is supported only on Android 13+"); }