49 lines
1.5 KiB
TypeScript
49 lines
1.5 KiB
TypeScript
import { useEffect } from 'react';
|
|
import type { ReactNode } from 'react';
|
|
import type { TranslationMap } from 'i18n';
|
|
import { I18nProvider, localeDirection } from 'i18n';
|
|
import { panelCatalogs } from 'officerdev';
|
|
import { uiCatalogs } from '@/components/locales';
|
|
import { useSettings } from 'state/useSettings';
|
|
import { FALLBACK_LOCALE, SHIPPED_LOCALES } from './locales';
|
|
import appEnGB from '../locales/en-GB.json';
|
|
import appPtPT from '../locales/pt-PT.json';
|
|
|
|
const appCatalogs: TranslationMap = { 'en-GB': appEnGB, 'pt-PT': appPtPT };
|
|
|
|
/**
|
|
* Deep-merges the three per-workspace catalogs (D6) into one map per shipped locale — `app.*` from
|
|
* officer-web, `panel.*` from officerdev's panel apps, `ui.*` from shared components.
|
|
*/
|
|
const translations: TranslationMap = Object.fromEntries(
|
|
SHIPPED_LOCALES.map(({ code }) => [
|
|
code,
|
|
{
|
|
app: appCatalogs[code] ?? {},
|
|
panel: panelCatalogs[code] ?? {},
|
|
ui: uiCatalogs[code] ?? {},
|
|
},
|
|
]),
|
|
);
|
|
|
|
type I18nBridgeProps = {
|
|
children: ReactNode;
|
|
};
|
|
|
|
export const I18nBridge = ({ children }: I18nBridgeProps) => {
|
|
const { settings } = useSettings();
|
|
const locale = settings.languages.default;
|
|
|
|
// Prepared for RTL (D3) — every shipped locale is `ltr` today, but the wiring exists so a future
|
|
// RTL catalog needs no second pass over the tree.
|
|
useEffect(() => {
|
|
document.documentElement.dir = localeDirection(locale);
|
|
}, [locale]);
|
|
|
|
return (
|
|
<I18nProvider translations={translations} locale={locale} fallbackLocale={FALLBACK_LOCALE}>
|
|
{children}
|
|
</I18nProvider>
|
|
);
|
|
};
|