Start implementing per theme variant translations and ability to add extra languages
This commit is contained in:
parent
e15f13646c
commit
aad89a2001
@ -1,6 +1,6 @@
|
|||||||
import type { GenericI18n_noJsx } from "./i18n";
|
import type { GenericI18n_noJsx } from "./i18n";
|
||||||
|
|
||||||
export type GenericI18n<MessageKey extends string> = GenericI18n_noJsx<MessageKey> & {
|
export type GenericI18n<MessageKey extends string, LanguageTag extends string> = GenericI18n_noJsx<MessageKey, LanguageTag> & {
|
||||||
msg: (key: MessageKey, ...args: (string | undefined)[]) => JSX.Element;
|
msg: (key: MessageKey, ...args: (string | undefined)[]) => JSX.Element;
|
||||||
advancedMsg: (key: string, ...args: (string | undefined)[]) => JSX.Element;
|
advancedMsg: (key: string, ...args: (string | undefined)[]) => JSX.Element;
|
||||||
};
|
};
|
||||||
|
@ -5,8 +5,12 @@ import { fetchMessages_defaultSet } from "./messages_defaultSet";
|
|||||||
import type { KcContext } from "../KcContext";
|
import type { KcContext } from "../KcContext";
|
||||||
import { FALLBACK_LANGUAGE_TAG } from "keycloakify/bin/shared/constants";
|
import { FALLBACK_LANGUAGE_TAG } from "keycloakify/bin/shared/constants";
|
||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
|
import { is } from "tsafe/is";
|
||||||
|
import { Reflect } from "tsafe/Reflect";
|
||||||
|
import type { LanguageTag as LanguageTag_defaultSet } from "keycloakify/login/i18n/messages_defaultSet/LanguageTag";
|
||||||
|
|
||||||
export type KcContextLike = {
|
export type KcContextLike = {
|
||||||
|
themeName: string;
|
||||||
locale?: {
|
locale?: {
|
||||||
currentLanguageTag: string;
|
currentLanguageTag: string;
|
||||||
supported: { languageTag: string; url: string; label: string }[];
|
supported: { languageTag: string; url: string; label: string }[];
|
||||||
@ -18,18 +22,18 @@ export type KcContextLike = {
|
|||||||
|
|
||||||
assert<KcContext extends KcContextLike ? true : false>();
|
assert<KcContext extends KcContextLike ? true : false>();
|
||||||
|
|
||||||
export type GenericI18n_noJsx<MessageKey extends string> = {
|
export type GenericI18n_noJsx<MessageKey extends string, LanguageTag extends string> = {
|
||||||
/**
|
/**
|
||||||
* e.g: "en", "fr", "zh-CN"
|
* e.g: "en", "fr", "zh-CN"
|
||||||
*
|
*
|
||||||
* The current language
|
* The current language
|
||||||
*/
|
*/
|
||||||
currentLanguageTag: string;
|
currentLanguageTag: LanguageTag;
|
||||||
/**
|
/**
|
||||||
* Redirect to this url to change the language.
|
* Redirect to this url to change the language.
|
||||||
* After reload currentLanguageTag === newLanguageTag
|
* After reload currentLanguageTag === newLanguageTag
|
||||||
*/
|
*/
|
||||||
getChangeLocaleUrl: (newLanguageTag: string) => string;
|
getChangeLocaleUrl: (newLanguageTag: LanguageTag) => string;
|
||||||
/**
|
/**
|
||||||
* e.g. "en" => "English", "fr" => "Français", ...
|
* e.g. "en" => "English", "fr" => "Français", ...
|
||||||
*
|
*
|
||||||
@ -81,10 +85,35 @@ export type GenericI18n_noJsx<MessageKey extends string> = {
|
|||||||
|
|
||||||
export type MessageKey_defaultSet = keyof typeof messages_defaultSet_fallbackLanguage;
|
export type MessageKey_defaultSet = keyof typeof messages_defaultSet_fallbackLanguage;
|
||||||
|
|
||||||
export function createGetI18n<MessageKey_themeDefined extends string = never>(messagesByLanguageTag_themeDefined: {
|
export type ReturnTypeOfCreateGetI18n<MessageKey_themeDefined extends string, LanguageTag_notInDefaultSet extends string> = {
|
||||||
[languageTag: string]: { [key in MessageKey_themeDefined]: string };
|
getI18n: (params: { kcContext: KcContextLike }) => {
|
||||||
}) {
|
i18n: GenericI18n_noJsx<MessageKey_defaultSet | MessageKey_themeDefined, LanguageTag_defaultSet | LanguageTag_notInDefaultSet>;
|
||||||
type I18n = GenericI18n_noJsx<MessageKey_defaultSet | MessageKey_themeDefined>;
|
prI18n_currentLanguage:
|
||||||
|
| Promise<GenericI18n_noJsx<MessageKey_defaultSet | MessageKey_themeDefined, LanguageTag_defaultSet | LanguageTag_notInDefaultSet>>
|
||||||
|
| undefined;
|
||||||
|
};
|
||||||
|
ofTypeI18n: GenericI18n_noJsx<MessageKey_defaultSet | MessageKey_themeDefined, LanguageTag_defaultSet | LanguageTag_notInDefaultSet>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createGetI18n<
|
||||||
|
ThemeName extends string = string,
|
||||||
|
MessageKey_themeDefined extends string = never,
|
||||||
|
LanguageTag_notInDefaultSet extends string = never
|
||||||
|
>(params: {
|
||||||
|
extraLanguageTranslations: {
|
||||||
|
[languageTag in LanguageTag_notInDefaultSet]: () => Promise<{ default: Record<MessageKey_defaultSet, string> }>;
|
||||||
|
};
|
||||||
|
messagesByLanguageTag_themeDefined: Partial<{
|
||||||
|
[languageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: {
|
||||||
|
[key in MessageKey_themeDefined]: string | Record<ThemeName, string>;
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
}): ReturnTypeOfCreateGetI18n<MessageKey_themeDefined, LanguageTag_notInDefaultSet> {
|
||||||
|
const { extraLanguageTranslations, messagesByLanguageTag_themeDefined } = params;
|
||||||
|
|
||||||
|
type LanguageTag = LanguageTag_defaultSet | LanguageTag_notInDefaultSet;
|
||||||
|
|
||||||
|
type I18n = GenericI18n_noJsx<MessageKey_defaultSet | MessageKey_themeDefined, LanguageTag>;
|
||||||
|
|
||||||
type Result = { i18n: I18n; prI18n_currentLanguage: Promise<I18n> | undefined };
|
type Result = { i18n: I18n; prI18n_currentLanguage: Promise<I18n> | undefined };
|
||||||
|
|
||||||
@ -104,7 +133,7 @@ export function createGetI18n<MessageKey_themeDefined extends string = never>(me
|
|||||||
}
|
}
|
||||||
|
|
||||||
const partialI18n: Pick<I18n, "currentLanguageTag" | "getChangeLocaleUrl" | "labelBySupportedLanguageTag"> = {
|
const partialI18n: Pick<I18n, "currentLanguageTag" | "getChangeLocaleUrl" | "labelBySupportedLanguageTag"> = {
|
||||||
currentLanguageTag: kcContext.locale?.currentLanguageTag ?? FALLBACK_LANGUAGE_TAG,
|
currentLanguageTag: kcContext.locale?.currentLanguageTag ?? (FALLBACK_LANGUAGE_TAG as any),
|
||||||
getChangeLocaleUrl: newLanguageTag => {
|
getChangeLocaleUrl: newLanguageTag => {
|
||||||
const { locale } = kcContext;
|
const { locale } = kcContext;
|
||||||
|
|
||||||
@ -120,15 +149,16 @@ export function createGetI18n<MessageKey_themeDefined extends string = never>(me
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { createI18nTranslationFunctions } = createI18nTranslationFunctionsFactory<MessageKey_themeDefined>({
|
const { createI18nTranslationFunctions } = createI18nTranslationFunctionsFactory<MessageKey_themeDefined>({
|
||||||
|
themeName: kcContext.themeName,
|
||||||
messages_themeDefined:
|
messages_themeDefined:
|
||||||
messagesByLanguageTag_themeDefined[partialI18n.currentLanguageTag] ??
|
messagesByLanguageTag_themeDefined[partialI18n.currentLanguageTag] ??
|
||||||
messagesByLanguageTag_themeDefined[FALLBACK_LANGUAGE_TAG] ??
|
messagesByLanguageTag_themeDefined[FALLBACK_LANGUAGE_TAG as LanguageTag] ??
|
||||||
(() => {
|
(() => {
|
||||||
const firstLanguageTag = Object.keys(messagesByLanguageTag_themeDefined)[0];
|
const firstLanguageTag = Object.keys(messagesByLanguageTag_themeDefined)[0];
|
||||||
if (firstLanguageTag === undefined) {
|
if (firstLanguageTag === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return messagesByLanguageTag_themeDefined[firstLanguageTag];
|
return messagesByLanguageTag_themeDefined[firstLanguageTag as LanguageTag];
|
||||||
})(),
|
})(),
|
||||||
messages_fromKcServer: kcContext["x-keycloakify"].messages
|
messages_fromKcServer: kcContext["x-keycloakify"].messages
|
||||||
});
|
});
|
||||||
@ -146,7 +176,29 @@ export function createGetI18n<MessageKey_themeDefined extends string = never>(me
|
|||||||
prI18n_currentLanguage: isCurrentLanguageFallbackLanguage
|
prI18n_currentLanguage: isCurrentLanguageFallbackLanguage
|
||||||
? undefined
|
? undefined
|
||||||
: (async () => {
|
: (async () => {
|
||||||
const messages_defaultSet_currentLanguage = await fetchMessages_defaultSet(partialI18n.currentLanguageTag);
|
const messages_defaultSet_currentLanguage = await (async () => {
|
||||||
|
const currentLanguageTag = partialI18n.currentLanguageTag;
|
||||||
|
|
||||||
|
const fromDefaultSet = await fetchMessages_defaultSet(currentLanguageTag);
|
||||||
|
|
||||||
|
const isEmpty = (() => {
|
||||||
|
for (let _key in fromDefaultSet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (isEmpty) {
|
||||||
|
assert(is<Exclude<LanguageTag, LanguageTag_defaultSet>>(currentLanguageTag));
|
||||||
|
|
||||||
|
const asyncFunction = extraLanguageTranslations[currentLanguageTag];
|
||||||
|
|
||||||
|
assert(asyncFunction !== undefined);
|
||||||
|
|
||||||
|
return asyncFunction().then(({ default: messages }) => messages);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
const i18n_currentLanguage: I18n = {
|
const i18n_currentLanguage: I18n = {
|
||||||
...partialI18n,
|
...partialI18n,
|
||||||
@ -170,18 +222,22 @@ export function createGetI18n<MessageKey_themeDefined extends string = never>(me
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { getI18n };
|
return {
|
||||||
|
getI18n,
|
||||||
|
ofTypeI18n: Reflect<I18n>()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createI18nTranslationFunctionsFactory<MessageKey_themeDefined extends string>(params: {
|
function createI18nTranslationFunctionsFactory<MessageKey_themeDefined extends string>(params: {
|
||||||
messages_themeDefined: Record<MessageKey_themeDefined, string> | undefined;
|
themeName: string;
|
||||||
|
messages_themeDefined: Record<MessageKey_themeDefined, string | Record<string, string>> | undefined;
|
||||||
messages_fromKcServer: Record<string, string>;
|
messages_fromKcServer: Record<string, string>;
|
||||||
}) {
|
}) {
|
||||||
const { messages_themeDefined, messages_fromKcServer } = params;
|
const { themeName, messages_themeDefined, messages_fromKcServer } = params;
|
||||||
|
|
||||||
function createI18nTranslationFunctions(params: {
|
function createI18nTranslationFunctions(params: {
|
||||||
messages_defaultSet_currentLanguage: Partial<Record<MessageKey_defaultSet, string>> | undefined;
|
messages_defaultSet_currentLanguage: Partial<Record<MessageKey_defaultSet, string>> | undefined;
|
||||||
}): Pick<GenericI18n_noJsx<MessageKey_defaultSet | MessageKey_themeDefined>, "msgStr" | "advancedMsgStr"> {
|
}): Pick<GenericI18n_noJsx<MessageKey_defaultSet | MessageKey_themeDefined, string>, "msgStr" | "advancedMsgStr"> {
|
||||||
const { messages_defaultSet_currentLanguage } = params;
|
const { messages_defaultSet_currentLanguage } = params;
|
||||||
|
|
||||||
function resolveMsg(props: { key: string; args: (string | undefined)[] }): string | undefined {
|
function resolveMsg(props: { key: string; args: (string | undefined)[] }): string | undefined {
|
||||||
@ -189,7 +245,23 @@ function createI18nTranslationFunctionsFactory<MessageKey_themeDefined extends s
|
|||||||
|
|
||||||
const message =
|
const message =
|
||||||
id<Record<string, string | undefined>>(messages_fromKcServer)[key] ??
|
id<Record<string, string | undefined>>(messages_fromKcServer)[key] ??
|
||||||
id<Record<string, string | undefined> | undefined>(messages_themeDefined)?.[key] ??
|
(() => {
|
||||||
|
const messageOrMap = id<Record<string, string | Record<string, string> | undefined> | undefined>(messages_themeDefined)?.[key];
|
||||||
|
|
||||||
|
if (messageOrMap === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof messageOrMap === "string") {
|
||||||
|
return messageOrMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = messageOrMap[themeName];
|
||||||
|
|
||||||
|
assert(message !== undefined, `No translation for theme variant "${themeName}" for key "${key}"`);
|
||||||
|
|
||||||
|
return message;
|
||||||
|
})() ??
|
||||||
id<Record<string, string | undefined> | undefined>(messages_defaultSet_currentLanguage)?.[key] ??
|
id<Record<string, string | undefined> | undefined>(messages_defaultSet_currentLanguage)?.[key] ??
|
||||||
id<Record<string, string | undefined>>(messages_defaultSet_fallbackLanguage)[key];
|
id<Record<string, string | undefined>>(messages_defaultSet_fallbackLanguage)[key];
|
||||||
|
|
||||||
|
@ -2,4 +2,4 @@ import type { GenericI18n } from "./GenericI18n";
|
|||||||
import type { MessageKey_defaultSet, KcContextLike } from "./i18n";
|
import type { MessageKey_defaultSet, KcContextLike } from "./i18n";
|
||||||
export type { MessageKey_defaultSet, KcContextLike };
|
export type { MessageKey_defaultSet, KcContextLike };
|
||||||
export type I18n = GenericI18n<MessageKey_defaultSet>;
|
export type I18n = GenericI18n<MessageKey_defaultSet>;
|
||||||
export { createUseI18n } from "./useI18n";
|
export { createUseI18n, i18nApi } from "./useI18n";
|
||||||
|
130
src/login/i18n/pinApi.ts
Normal file
130
src/login/i18n/pinApi.ts
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import type { LanguageTag as LanguageTag_defaultSet } from "keycloakify/login/i18n/messages_defaultSet/LanguageTag";
|
||||||
|
import {
|
||||||
|
type MessageKey_defaultSet,
|
||||||
|
type ReturnTypeOfCreateGetI18n,
|
||||||
|
createGetI18n
|
||||||
|
} from "./i18n";
|
||||||
|
|
||||||
|
export type I18nInitializer<
|
||||||
|
ThemeName extends string = never,
|
||||||
|
MessageKey_themeDefined extends string = never,
|
||||||
|
LanguageTag_notInDefaultSet extends string = never,
|
||||||
|
ExcludedMethod extends
|
||||||
|
| "withThemeName"
|
||||||
|
| "withExtraLanguages"
|
||||||
|
| "withCustomTranslations" = never
|
||||||
|
> = Omit<
|
||||||
|
{
|
||||||
|
withThemeName: <ThemeName extends string>() => I18nInitializer<
|
||||||
|
ThemeName,
|
||||||
|
MessageKey_themeDefined,
|
||||||
|
LanguageTag_notInDefaultSet,
|
||||||
|
ExcludedMethod | "withThemeName"
|
||||||
|
>;
|
||||||
|
withExtraLanguages: <
|
||||||
|
LanguageTag_notInDefaultSet extends string
|
||||||
|
>(extraLanguageTranslations: {
|
||||||
|
[LanguageTag in LanguageTag_notInDefaultSet]: () => Promise<
|
||||||
|
Record<MessageKey_defaultSet, string>
|
||||||
|
>;
|
||||||
|
}) => I18nInitializer<
|
||||||
|
ThemeName,
|
||||||
|
MessageKey_themeDefined,
|
||||||
|
LanguageTag_notInDefaultSet,
|
||||||
|
ExcludedMethod | "withExtraLanguages"
|
||||||
|
>;
|
||||||
|
withCustomTranslations: <MessageKey_themeDefined extends string>(
|
||||||
|
messagesByLanguageTag_themeDefined: Partial<{
|
||||||
|
[LanguageTag in
|
||||||
|
| LanguageTag_defaultSet
|
||||||
|
| LanguageTag_notInDefaultSet]: Record<
|
||||||
|
MessageKey_themeDefined,
|
||||||
|
string | Record<ThemeName, string>
|
||||||
|
>;
|
||||||
|
}>
|
||||||
|
) => I18nInitializer<
|
||||||
|
ThemeName,
|
||||||
|
MessageKey_themeDefined,
|
||||||
|
LanguageTag_notInDefaultSet,
|
||||||
|
ExcludedMethod | "withCustomTranslations"
|
||||||
|
>;
|
||||||
|
create: () => ReturnTypeOfCreateGetI18n<
|
||||||
|
MessageKey_themeDefined,
|
||||||
|
LanguageTag_notInDefaultSet
|
||||||
|
>;
|
||||||
|
},
|
||||||
|
ExcludedMethod
|
||||||
|
>;
|
||||||
|
|
||||||
|
function createI18nInitializer<
|
||||||
|
ThemeName extends string = never,
|
||||||
|
MessageKey_themeDefined extends string = never,
|
||||||
|
LanguageTag_notInDefaultSet extends string = never
|
||||||
|
>(params: {
|
||||||
|
extraLanguageTranslations: {
|
||||||
|
[LanguageTag in LanguageTag_notInDefaultSet]: () => Promise<
|
||||||
|
Record<MessageKey_defaultSet, string>
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
messagesByLanguageTag_themeDefined: Partial<{
|
||||||
|
[LanguageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: Record<
|
||||||
|
MessageKey_themeDefined,
|
||||||
|
string | Record<ThemeName, string>
|
||||||
|
>;
|
||||||
|
}>;
|
||||||
|
}): I18nInitializer<ThemeName, MessageKey_themeDefined, LanguageTag_notInDefaultSet> {
|
||||||
|
const i18nInitializer: I18nInitializer<
|
||||||
|
ThemeName,
|
||||||
|
MessageKey_themeDefined,
|
||||||
|
LanguageTag_notInDefaultSet
|
||||||
|
> = {
|
||||||
|
withThemeName: () =>
|
||||||
|
createI18nInitializer({
|
||||||
|
extraLanguageTranslations: params.extraLanguageTranslations,
|
||||||
|
messagesByLanguageTag_themeDefined:
|
||||||
|
params.messagesByLanguageTag_themeDefined as any
|
||||||
|
}),
|
||||||
|
withExtraLanguages: extraLanguageTranslations =>
|
||||||
|
createI18nInitializer({
|
||||||
|
extraLanguageTranslations,
|
||||||
|
messagesByLanguageTag_themeDefined:
|
||||||
|
params.messagesByLanguageTag_themeDefined as any
|
||||||
|
}),
|
||||||
|
withCustomTranslations: messagesByLanguageTag_themeDefined =>
|
||||||
|
createI18nInitializer({
|
||||||
|
extraLanguageTranslations: params.extraLanguageTranslations,
|
||||||
|
messagesByLanguageTag_themeDefined
|
||||||
|
}),
|
||||||
|
create: () =>
|
||||||
|
createGetI18n({
|
||||||
|
extraLanguageTranslations: params.extraLanguageTranslations,
|
||||||
|
messagesByLanguageTag_themeDefined:
|
||||||
|
params.messagesByLanguageTag_themeDefined
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return i18nInitializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const i18nInitializer = createI18nInitializer({});
|
||||||
|
|
||||||
|
const i18n = i18nInitializer
|
||||||
|
.withThemeName<"my-theme-1" | "my-theme-2">()
|
||||||
|
.withExtraLanguages({
|
||||||
|
xx: async () => ({}) as any
|
||||||
|
})
|
||||||
|
.withCustomTranslations({
|
||||||
|
en: {
|
||||||
|
myCustomKey: {
|
||||||
|
"my-theme-1": "my-theme-1-en",
|
||||||
|
"my-theme-2": "my-theme-2-en"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xx: {
|
||||||
|
myCustomKey: {
|
||||||
|
"my-theme-1": "my-theme-1-xx",
|
||||||
|
"my-theme-2": "my-theme-2-xx"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
@ -2,16 +2,33 @@ import { useEffect, useState } from "react";
|
|||||||
import { createGetI18n, type GenericI18n_noJsx, type KcContextLike, type MessageKey_defaultSet } from "./i18n";
|
import { createGetI18n, type GenericI18n_noJsx, type KcContextLike, type MessageKey_defaultSet } from "./i18n";
|
||||||
import { GenericI18n } from "./GenericI18n";
|
import { GenericI18n } from "./GenericI18n";
|
||||||
import { Reflect } from "tsafe/Reflect";
|
import { Reflect } from "tsafe/Reflect";
|
||||||
|
import type { LanguageTag as LanguageTag_defaultSet } from "keycloakify/login/i18n/messages_defaultSet/LanguageTag";
|
||||||
|
|
||||||
export function createUseI18n<MessageKey_themeDefined extends string = never>(messagesByLanguageTag: {
|
export const i18nApi = {
|
||||||
[languageTag: string]: { [key in MessageKey_themeDefined]: string };
|
withThemeName: <ThemeName extends string>() => ({
|
||||||
|
withTranslations: <MessageKey_themeDefined extends string = never>(messagesByLanguageTag: {
|
||||||
|
[languageTag: string]: { [key in MessageKey_themeDefined]: string | Record<ThemeName, string> };
|
||||||
|
}) => ({
|
||||||
|
create: () => createUseI18n<MessageKey_themeDefined, ThemeName>(messagesByLanguageTag)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createUseI18n<
|
||||||
|
MessageKey_themeDefined extends string = never,
|
||||||
|
ThemeName extends string = string,
|
||||||
|
LanguageTag extends string = LanguageTag_defaultSet
|
||||||
|
>(params: {
|
||||||
|
messagesByLanguageTag: {
|
||||||
|
[languageTag: string]: { [key in MessageKey_themeDefined]: string | Record<ThemeName, string> };
|
||||||
|
};
|
||||||
}) {
|
}) {
|
||||||
type MessageKey = MessageKey_defaultSet | MessageKey_themeDefined;
|
type MessageKey = MessageKey_defaultSet | MessageKey_themeDefined;
|
||||||
|
|
||||||
type I18n = GenericI18n<MessageKey>;
|
type I18n = GenericI18n<MessageKey, LanguageTag>;
|
||||||
|
|
||||||
const { withJsx } = (() => {
|
const { withJsx } = (() => {
|
||||||
const cache = new WeakMap<GenericI18n_noJsx<MessageKey>, GenericI18n<MessageKey>>();
|
const cache = new WeakMap<GenericI18n_noJsx<MessageKey, LanguageTag>, GenericI18n<MessageKey, LanguageTag>>();
|
||||||
|
|
||||||
function renderHtmlString(params: { htmlString: string; msgKey: string }): JSX.Element {
|
function renderHtmlString(params: { htmlString: string; msgKey: string }): JSX.Element {
|
||||||
const { htmlString, msgKey } = params;
|
const { htmlString, msgKey } = params;
|
||||||
@ -25,7 +42,7 @@ export function createUseI18n<MessageKey_themeDefined extends string = never>(me
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function withJsx(i18n_noJsx: GenericI18n_noJsx<MessageKey>): I18n {
|
function withJsx(i18n_noJsx: GenericI18n_noJsx<MessageKey, LanguageTag>): I18n {
|
||||||
use_cache: {
|
use_cache: {
|
||||||
const i18n = cache.get(i18n_noJsx);
|
const i18n = cache.get(i18n_noJsx);
|
||||||
|
|
||||||
@ -63,7 +80,7 @@ export function createUseI18n<MessageKey_themeDefined extends string = never>(me
|
|||||||
(styleElement.textContent = `[data-kc-msg] { display: inline-block; }`), document.head.prepend(styleElement);
|
(styleElement.textContent = `[data-kc-msg] { display: inline-block; }`), document.head.prepend(styleElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { getI18n } = createGetI18n(messagesByLanguageTag);
|
const { getI18n } = createGetI18n({ messagesByLanguageTag, extraLanguageTranslations });
|
||||||
|
|
||||||
function useI18n(params: { kcContext: KcContextLike }): { i18n: I18n } {
|
function useI18n(params: { kcContext: KcContextLike }): { i18n: I18n } {
|
||||||
const { kcContext } = params;
|
const { kcContext } = params;
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export type { ExtendKcContext, Attribute } from "keycloakify/login/KcContext";
|
export type { ExtendKcContext, Attribute } from "keycloakify/login/KcContext";
|
||||||
export type { ClassKey } from "keycloakify/login/TemplateProps";
|
export type { ClassKey } from "keycloakify/login/TemplateProps";
|
||||||
export { createUseI18n } from "keycloakify/login/i18n";
|
export { createUseI18n, i18nApi } from "keycloakify/login/i18n";
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import { createUseI18n } from "../../dist/login";
|
import { i18nApi } from "../../dist/login";
|
||||||
|
import type { ThemeName } from "../kc.gen";
|
||||||
|
|
||||||
export const { useI18n, ofTypeI18n } = createUseI18n({});
|
export const { useI18n, ofTypeI18n } = i18nApi
|
||||||
|
.withThemeName<ThemeName>()
|
||||||
|
.withTranslations({})
|
||||||
|
.create();
|
||||||
|
|
||||||
export type I18n = typeof ofTypeI18n;
|
export type I18n = typeof ofTypeI18n;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user