alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
70 lines (63 loc) • 2.01 kB
text/typescript
import { $inject, type Async, createPrimitive, KIND, Primitive } from "alepha";
import { I18nProvider } from "../providers/I18nProvider.ts";
/**
* Register a dictionary entry for translations.
*
* It allows you to define a set of translations for a specific language.
* Entry can be lazy-loaded, which is useful for large dictionaries or when translations are not needed immediately.
*
* @example
* ```ts
* import { $dictionary } from "alepha/react/i18n";
*
* const Example = () => {
* const { tr } = useI18n<App, "en">();
* return <div>{tr("hello")}</div>; //
* }
*
* class App {
*
* en = $dictionary({
* // { default: { hello: "Hey" } }
* lazy: () => import("./translations/en.ts"),
* });
*
* home = $page({
* path: "/",
* component: Example,
* })
* }
*
* run(App);
* ```
*/
export const $dictionary = <T extends Record<string, string>>(
options: DictionaryPrimitiveOptions<T>,
): DictionaryPrimitive<T> => {
return createPrimitive(DictionaryPrimitive<T>, options);
};
// ---------------------------------------------------------------------------------------------------------------------
export interface DictionaryPrimitiveOptions<T extends Record<string, string>> {
lang?: string;
name?: string;
lazy: () => Async<{ default: T }>;
}
// ---------------------------------------------------------------------------------------------------------------------
export class DictionaryPrimitive<
T extends Record<string, string>,
> extends Primitive<DictionaryPrimitiveOptions<T>> {
protected provider = $inject(I18nProvider);
protected onInit() {
this.provider.registry.push({
target: this.config.service.name,
name: this.options.name ?? this.config.propertyKey,
lang: this.options.lang ?? this.config.propertyKey,
loader: async () => {
const mod = await this.options.lazy();
return mod.default;
},
translations: {},
});
}
}
$dictionary[KIND] = DictionaryPrimitive;