78 lines
2.4 KiB
TypeScript
Executable File
78 lines
2.4 KiB
TypeScript
Executable File
import { DirectionProvider } from '@radix-ui/react-direction';
|
|
import { useEffect, useState, type PropsWithChildren } from 'react';
|
|
import { IntlProvider } from 'react-intl';
|
|
import { LocalStorageService } from '@crux-kit/local-storage';
|
|
import { I18N_DEFAULT_LANGUAGE, I18N_LANGUAGES } from '#app/i18n/config';
|
|
import TranslationsContext from '#app/i18n/context';
|
|
import { type Language, type LanguageCode } from '#app/i18n/types';
|
|
import { IntlDate } from '#infrastructure/IntlDate';
|
|
import { IntlName } from '#infrastructure/IntlName';
|
|
import '@formatjs/intl-relativetimeformat/polyfill';
|
|
import '@formatjs/intl-relativetimeformat/locale-data/en';
|
|
|
|
const storage = new LocalStorageService({ prefix: 'i18n' });
|
|
|
|
const resolveLanguage = (code?: LanguageCode): Language => {
|
|
return I18N_LANGUAGES.find((lang) => lang.code === code) ?? I18N_DEFAULT_LANGUAGE;
|
|
};
|
|
|
|
const getInitialLanguage = () => {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const langParam = urlParams.get('lang');
|
|
|
|
if (langParam) {
|
|
const matchedLanguage = I18N_LANGUAGES.find((lang) => lang.code === langParam);
|
|
if (matchedLanguage) {
|
|
storage.set('config', matchedLanguage.code);
|
|
return matchedLanguage;
|
|
}
|
|
}
|
|
|
|
return resolveLanguage(storage.get<LanguageCode>('config'));
|
|
};
|
|
|
|
const initialLanguage = getInitialLanguage();
|
|
|
|
IntlDate.setLocaleGlobally(initialLanguage.code);
|
|
IntlName.setLanguage(initialLanguage.code);
|
|
|
|
const I18nProvider = ({ children }: PropsWithChildren) => {
|
|
const [currenLanguage, setCurrenLanguage] = useState(initialLanguage);
|
|
|
|
const changeLanguage = (language: Language) => {
|
|
storage.set('config', language.code);
|
|
IntlDate.setLocaleGlobally(language.code);
|
|
IntlName.setLanguage(language.code);
|
|
setCurrenLanguage(language);
|
|
};
|
|
|
|
const isRTL = () => {
|
|
return currenLanguage.direction === 'rtl';
|
|
};
|
|
|
|
useEffect(() => {
|
|
document.documentElement.setAttribute('dir', currenLanguage.direction);
|
|
}, [currenLanguage]);
|
|
|
|
return (
|
|
<TranslationsContext.Provider
|
|
value={{
|
|
languages: I18N_LANGUAGES,
|
|
isRTL,
|
|
currenLanguage,
|
|
changeLanguage
|
|
}}
|
|
>
|
|
<IntlProvider
|
|
messages={currenLanguage.messages}
|
|
locale={currenLanguage.code}
|
|
defaultLocale={I18N_DEFAULT_LANGUAGE.code}
|
|
>
|
|
<DirectionProvider dir={currenLanguage.direction}>{children}</DirectionProvider>
|
|
</IntlProvider>
|
|
</TranslationsContext.Provider>
|
|
);
|
|
};
|
|
|
|
export default I18nProvider;
|