core-app-api: add support for explicit configuration of default language
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
+11
-3
@@ -25,6 +25,7 @@ export const DEFAULT_LANGUAGE = 'en';
|
||||
|
||||
/** @alpha */
|
||||
export interface AppLanguageSelectorOptions {
|
||||
defaultLanguage?: string;
|
||||
availableLanguages?: string[];
|
||||
}
|
||||
|
||||
@@ -47,7 +48,14 @@ export class AppLanguageSelector implements AppLanguageApi {
|
||||
throw new Error(`Supported languages must include '${DEFAULT_LANGUAGE}'`);
|
||||
}
|
||||
|
||||
return new AppLanguageSelector(languages);
|
||||
const initialLanguage = options?.defaultLanguage ?? DEFAULT_LANGUAGE;
|
||||
if (!languages.includes(initialLanguage)) {
|
||||
throw new Error(
|
||||
`Initial language must be one of the supported languages, got '${initialLanguage}'`,
|
||||
);
|
||||
}
|
||||
|
||||
return new AppLanguageSelector(languages, initialLanguage);
|
||||
}
|
||||
|
||||
static createWithStorage(options?: AppLanguageSelectorOptions) {
|
||||
@@ -85,9 +93,9 @@ export class AppLanguageSelector implements AppLanguageApi {
|
||||
#language: string;
|
||||
#subject: BehaviorSubject<{ language: string }>;
|
||||
|
||||
private constructor(languages: string[]) {
|
||||
private constructor(languages: string[], initialLanguage: string) {
|
||||
this.#languages = languages;
|
||||
this.#language = languages[0];
|
||||
this.#language = initialLanguage;
|
||||
this.#subject = new BehaviorSubject<{ language: string }>({
|
||||
language: this.#language,
|
||||
});
|
||||
|
||||
+23
@@ -193,6 +193,29 @@ describe('I18nextTranslationApi', () => {
|
||||
expect(snapshot.t('foo')).toBe('OtherFoo');
|
||||
});
|
||||
|
||||
it('should allow initial language to not be the default one', async () => {
|
||||
const languageApi = AppLanguageSelector.create({
|
||||
defaultLanguage: 'sv',
|
||||
availableLanguages: ['en', 'sv'],
|
||||
});
|
||||
const translationApi = I18nextTranslationApi.create({
|
||||
languageApi,
|
||||
resources: [
|
||||
createTranslationResource({
|
||||
ref: plainRef,
|
||||
translations: {
|
||||
sv: () => Promise.resolve({ default: { foo: 'Föö' } }),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const snapshot = assertReady(
|
||||
await waitForNext(translationApi.translation$(plainRef), s => s.ready),
|
||||
);
|
||||
expect(snapshot.t('foo')).toBe('Föö');
|
||||
});
|
||||
|
||||
it('should prefer the last loaded resource', async () => {
|
||||
const languageApi = AppLanguageSelector.create({
|
||||
availableLanguages: ['en', 'sv'],
|
||||
|
||||
@@ -155,6 +155,11 @@ export class I18nextTranslationApi implements TranslationApi {
|
||||
|
||||
i18n.init();
|
||||
|
||||
const { language: initialLanguage } = options.languageApi.getLanguage();
|
||||
if (initialLanguage !== DEFAULT_LANGUAGE) {
|
||||
i18n.changeLanguage(initialLanguage);
|
||||
}
|
||||
|
||||
const loader = new ResourceLoader(loaded => {
|
||||
i18n.addResourceBundle(
|
||||
loaded.language,
|
||||
|
||||
@@ -182,6 +182,7 @@ export class AppManager implements BackstageApp {
|
||||
this.bindRoutes = options.bindRoutes;
|
||||
this.apiFactoryRegistry = new ApiFactoryRegistry();
|
||||
this.appLanguageApi = AppLanguageSelector.createWithStorage({
|
||||
defaultLanguage: options.__experimentalTranslations?.defaultLanguage,
|
||||
availableLanguages:
|
||||
options.__experimentalTranslations?.availableLanguages,
|
||||
});
|
||||
|
||||
@@ -284,6 +284,7 @@ export type AppOptions = {
|
||||
bindRoutes?(context: { bind: AppRouteBinder }): void;
|
||||
|
||||
__experimentalTranslations?: {
|
||||
defaultLanguage?: string;
|
||||
availableLanguages?: string[];
|
||||
resources?: Array<TranslationMessages | TranslationResource>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user