UNPKG

react-native-localize

Version:

A toolbox for your React Native app localization.

171 lines (170 loc) 5.71 kB
"use strict"; import { createContext, createElement, useContext, useState } from "react"; import { CURRENCIES, USES_FAHRENHEIT, USES_IMPERIAL, USES_RTL_LAYOUT } from "./constants"; import { getFindBestLanguageTag } from "./utils"; const dateTimeFormatters = new Map(); const numberFormatters = new Map(); const extractLanguageTag = languageTag => { const [language = "en", country] = languageTag.split("-"); return { languageCode: language.toLowerCase(), countryCode: country ? (country === "419" ? "UN" : country).toUpperCase() : undefined }; }; const convertLanguageTagToLocale = (languageTag, countryFallback) => { const { languageCode, countryCode = countryFallback } = extractLanguageTag(languageTag); return { languageCode, countryCode, languageTag: `${languageCode}-${countryCode}`, isRTL: USES_RTL_LAYOUT.has(languageCode) }; }; const getCountryImpl = languages => { for (const language of languages) { const { countryCode } = extractLanguageTag(language); if (countryCode) { return countryCode; } } return "US"; }; const getCurrenciesImpl = languages => { const currencies = []; for (const language of languages) { const { countryCode } = extractLanguageTag(language); if (countryCode) { const currency = CURRENCIES[countryCode]; if (currency && !currencies.includes(currency)) { currencies.push(currency); } } } if (currencies.length === 0) { currencies.push("USD"); } return currencies; }; const getLocalesImpl = (languages, country) => { const seen = new Set(); const locales = []; for (const language of languages) { const locale = convertLanguageTagToLocale(language, country); if (!seen.has(locale.languageTag)) { locales.push(locale); seen.add(locale.languageTag); } } return locales; }; const getNumberFormatSettingsImpl = language => { let formatter = numberFormatters.get(language); if (formatter == null) { formatter = new Intl.NumberFormat(language); numberFormatters.set(language, formatter); } const separators = formatter.format(1000000.1).replace(/\d/g, ""); return { decimalSeparator: separators[separators.length - 1] || ".", groupingSeparator: separators[0] || "," }; }; const getTemperatureUnitImpl = country => USES_FAHRENHEIT.has(country) ? "fahrenheit" : "celsius"; const getTimeZoneImpl = language => { let formatter = dateTimeFormatters.get(language); if (formatter == null) { formatter = new Intl.DateTimeFormat(language, { hour: "numeric" }); dateTimeFormatters.set(language, formatter); } return formatter.resolvedOptions().timeZone || "Etc/UTC"; }; const uses24HourClockImpl = language => { let formatter = dateTimeFormatters.get(language); if (formatter == null) { formatter = new Intl.DateTimeFormat(language, { hour: "numeric" }); dateTimeFormatters.set(language, formatter); } return !formatter.format(new Date(2000, 0, 1, 20)).match(/am|pm/i); }; const usesMetricSystemImpl = country => !USES_IMPERIAL.has(country); export const getCalendar = () => "gregorian"; export const getCountry = () => getCountryImpl(navigator.languages); export const getCurrencies = () => getCurrenciesImpl(navigator.languages); export const getLocales = () => { const { languages } = navigator; return getLocalesImpl(languages, getCountryImpl(languages)); }; export const getNumberFormatSettings = () => getNumberFormatSettingsImpl(navigator.language); export const getTemperatureUnit = () => getTemperatureUnitImpl(getCountryImpl(navigator.languages)); export const getTimeZone = () => getTimeZoneImpl(navigator.language); export const uses24HourClock = () => uses24HourClockImpl(navigator.language); export const usesMetricSystem = () => usesMetricSystemImpl(getCountryImpl(navigator.languages)); export const usesAutoDateAndTime = () => undefined; export const usesAutoTimeZone = () => undefined; export const findBestLanguageTag = getFindBestLanguageTag(getLocales()); export const openAppLanguageSettings = async () => { throw new Error("openAppLanguageSettings is supported only on Android 13+"); }; const ServerLanguagesContext = /*#__PURE__*/createContext(null); export const ServerLanguagesProvider = ({ children, value }) => typeof window === "undefined" ? /*#__PURE__*/createElement(ServerLanguagesContext.Provider, { children, value }) : children; const api = { getCalendar, getCountry, getCurrencies, getLocales, getNumberFormatSettings, getTemperatureUnit, getTimeZone, uses24HourClock, usesMetricSystem, usesAutoDateAndTime, usesAutoTimeZone, findBestLanguageTag, openAppLanguageSettings }; export const useLocalize = () => { const languages = useContext(ServerLanguagesContext); return useState(() => { if (languages == null) { return api; } const [language = "en"] = languages; const country = getCountryImpl(languages); const locales = getLocalesImpl(languages, country); return { getCalendar, getCountry: () => country, getCurrencies: () => getCurrenciesImpl(languages), getLocales: () => locales, getNumberFormatSettings: () => getNumberFormatSettingsImpl(language), getTemperatureUnit: () => getTemperatureUnitImpl(country), getTimeZone: () => getTimeZoneImpl(language), uses24HourClock: () => uses24HourClockImpl(language), usesMetricSystem: () => usesMetricSystemImpl(country), usesAutoDateAndTime, usesAutoTimeZone, findBestLanguageTag: getFindBestLanguageTag(locales), openAppLanguageSettings }; })[0]; }; //# sourceMappingURL=module.js.map