UNPKG

laravel-i18n-react

Version:

A Vite plugin to load Laravel localization files and provide them to React applications.

175 lines (174 loc) 6.56 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var _a, _b; import { createElement, useEffect, useState } from 'react'; import { Context } from './context'; import pluralization from './utils/pluralization'; import recognizer from './utils/recognizer'; import replacer from './utils/replacer'; import resolver from './utils/resolver'; /** * */ const isServer = typeof window === 'undefined'; /** * Map object for translations. */ const translation = new Map(); /** * Get document lang meta from HTML. */ const documentLang = typeof document !== 'undefined' ? ((_b = (_a = document === null || document === void 0 ? void 0 : document.documentElement) === null || _a === void 0 ? void 0 : _a.lang) === null || _b === void 0 ? void 0 : _b.replace('-', '_')) || 'en' : 'en'; /** * The default options. */ const defaultOptions = { locale: documentLang, fallbackLocale: documentLang, prevLocale: documentLang, files: {} }; /** * Laravel React I18n Provider: */ export default function LaravelReactI18nProvider(_a) { var { children, ssr } = _a, currentOptions = __rest(_a, ["children", "ssr"]); const [isFirstRender, setIsFirstRender] = useState(true); const [loading, setLoading] = useState(!isServer); const [options, setOptions] = useState(Object.assign(Object.assign({}, defaultOptions), currentOptions)); const { getLocales, isLocale } = recognizer(options.files); // Determine if files are eagerly loaded. const filesAreEagerlyLoaded = Object.values(options.files).every((value) => typeof value === 'object' && value !== null); const { locale, fallbackLocale } = options; if (!translation.get(locale)) { if (filesAreEagerlyLoaded) { fetchLocaleSync(locale); } else if (isServer) { fetchLocaleServer(locale); } } if (locale !== fallbackLocale && !translation.get(fallbackLocale)) { if (filesAreEagerlyLoaded) { fetchLocaleSync(fallbackLocale); } else if (isServer) { fetchLocaleServer(fallbackLocale); } } useEffect(() => { if (!filesAreEagerlyLoaded) { if (!translation.get(locale)) fetchLocaleClient(locale); if (locale !== fallbackLocale && !translation.get(fallbackLocale)) fetchLocaleClient(fallbackLocale); } }, [options.locale]); function fetchLocaleSync(locale) { const responses = resolver(options.files, locale); for (const response of responses) { translation.set(locale, Object.assign(Object.assign({}, (translation.get(locale) || {})), response.default)); } } /** * Initialise translations for server. */ if (isServer) { const { locale, fallbackLocale } = options; if (!translation.get(locale)) fetchLocaleServer(locale); if (locale !== fallbackLocale && !translation.get(fallbackLocale)) fetchLocaleServer(fallbackLocale); } /** * Fetching locale for client side. */ function fetchLocaleClient(locale) { const promises = resolver(options.files, locale); setLoading(true); Promise.all(promises) .then((responses) => { for (const response of responses) { translation.set(locale, Object.assign(Object.assign({}, (translation.get(locale) || {})), response.default)); } }) .then(() => { if (isFirstRender) setIsFirstRender(false); setLoading(false); }); } /** * Fetching locale for server side. */ function fetchLocaleServer(locale) { const responses = resolver(options.files, locale); for (const response of responses) { translation.set(locale, Object.assign(Object.assign({}, (translation.get(locale) || {})), response.default)); } } /** * Get the translation for the given key. */ function t(key, replacements = {}) { var _a, _b, _c, _d; const { locale, fallbackLocale, prevLocale } = options; let message = ((_a = translation.get(fallbackLocale)) === null || _a === void 0 ? void 0 : _a[key]) ? translation.get(fallbackLocale)[key] : key; if (isLocale(locale)) { if ((_b = translation.get(locale)) === null || _b === void 0 ? void 0 : _b[key]) { message = translation.get(locale)[key]; } else if ((_c = translation.get(prevLocale)) === null || _c === void 0 ? void 0 : _c[key]) { message = translation.get(prevLocale)[key]; } else if ((_d = translation.get(fallbackLocale)) === null || _d === void 0 ? void 0 : _d[key]) { message = translation.get(fallbackLocale)[key]; } } return replacer(message, replacements); } /** * Translates the given message based on a count. */ function tChoice(key, number, replacements = {}) { const message = t(key, replacements); const locale = isLocale(options.locale) ? options.locale : options.fallbackLocale; return replacer(pluralization(message, number, locale), Object.assign(Object.assign({}, replacements), { count: number.toString() })); } /** * Set locale. */ function setLocale(locale) { if (!isServer) { // When setting the HTML lang attribute, hyphen must be use instead of underscore. document.documentElement.setAttribute('lang', locale.replace('_', '-')); } setOptions((prevState) => (Object.assign(Object.assign({}, options), { locale, prevLocale: prevState.locale }))); } /** * Current locale. */ function currentLocale() { return options.locale || options.fallbackLocale; } return createElement(Context.Provider, { value: { t, tChoice, loading, isLocale, getLocales, currentLocale, setLocale } }, children); }