react-native-localize
Version:
A toolbox for your React Native app localization.
171 lines (170 loc) • 5.71 kB
JavaScript
;
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