alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
257 lines • 9.96 kB
TypeScript
import { Alepha, Async, KIND, Primitive, TypeBoxError } from "alepha";
import { DateTime, DateTimeProvider } from "alepha/datetime";
import { RouterLocaleProvider } from "alepha/react/router";
//#region ../../src/react/i18n/components/Localize.d.ts
interface LocalizeProps {
value: string | number | Date | DateTime | TypeBoxError;
/**
* Options for number formatting (when value is a number)
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat
*/
number?: Intl.NumberFormatOptions;
/**
* Options for date formatting (when value is a Date or DateTime)
* Can be:
* - A dayjs format string (e.g., "LLL", "YYYY-MM-DD", "dddd, MMMM D YYYY")
* - "fromNow" for relative time (e.g., "2 hours ago")
* - Intl.DateTimeFormatOptions for native formatting
* @see https://day.js.org/docs/en/display/format
* @see https://day.js.org/docs/en/display/from-now
*/
date?: string | "fromNow" | Intl.DateTimeFormatOptions;
/**
* Timezone to display dates in (when value is a Date or DateTime)
* Uses IANA timezone names (e.g., "America/New_York", "Europe/Paris", "Asia/Tokyo")
* @see https://day.js.org/docs/en/timezone/timezone
*/
timezone?: string;
}
declare const Localize: (props: LocalizeProps) => string | number;
//#endregion
//#region ../../src/react/i18n/components/Translate.d.ts
interface TranslateProps {
/**
* Dictionary key to look up — the same key you would pass to `tr(...)`.
*/
k: string;
/**
* Positional substitutions for `$1`, `$2`, … placeholders in the entry.
*/
args?: string[];
/**
* Shown when the key is missing from every registered dictionary (otherwise
* the raw key is rendered, matching `tr`'s behaviour).
*/
fallback?: string;
}
/**
* Renders a translated dictionary entry as a reactive text node.
*
* `tr(...)` is a hook, so it can only be called inside a component body. Use
* `<Translate>` wherever a *node* is expected instead — a prop, a `children`
* slot, or route metadata such as a nav-shell `label`. Because it subscribes to
* {@link useI18n} it re-renders on a language switch, unlike a string resolved
* once at module/initialisation time.
*
* Sibling of {@link Localize}: `Localize` formats a value (number, date,
* error); `Translate` looks up a key.
*
* @example
* ```tsx
* nav: { label: <Translate k="admin.nav.users" /> }
* <Translate k="cart.items" args={[String(count)]} fallback="Items" />
* ```
*/
declare const Translate: (props: TranslateProps) => import("react").JSX.Element;
/**
* Terse alias for {@link Translate} — handy in dense JSX such as nav labels.
*/
declare const Tr: typeof Translate;
//#endregion
//#region ../../src/react/i18n/providers/I18nProvider.d.ts
declare class I18nProvider<S extends object, K extends keyof ServiceDictionary<S>> {
protected log: import("alepha/logger").Logger;
protected alepha: Alepha;
protected dateTimeProvider: DateTimeProvider;
protected cookie: import("alepha/server/cookies").AbstractCookiePrimitive<import("zod").ZodString>;
readonly registry: Array<{
target: string;
name: string;
lang: string;
loader: () => Promise<Record<string, string>>;
translations: Record<string, string>;
}>;
options: {
fallbackLang: string;
autoDetect: boolean;
routing: "none" | "prefix";
};
/**
* Lazily-resolved locale-prefix router integration. Present only when both
* the router module is registered AND `routing: "prefix"` was configured —
* otherwise i18n stays fully standalone.
*/
protected localeProviderResolved: boolean;
protected localeProviderRef?: RouterLocaleProvider;
protected get localeProvider(): RouterLocaleProvider | undefined;
dateFormat: {
format: (value: Date) => string;
};
numberFormat: {
format: (value: number) => string;
};
get languages(): string[];
constructor();
/**
* Configure locale-prefix routing on the router, before the SSR routes are
* registered (`priority: "first"` runs ahead of the router's own `configure`
* hook). No-op unless `routing: "prefix"` and the router module is present.
*/
protected readonly onConfigure: import("alepha").HookPrimitive<"configure">;
protected readonly onRender: import("alepha").HookPrimitive<"server:onRequest">;
/**
* Detects the language carried by the request URL when `routing: "prefix"` is
* active. Returns the locale for any URL (the prefixed one for `/fr/...`, the
* default for an unprefixed path), or `undefined` when prefix routing is off.
*/
protected detectUrlLocale(pathname: string | undefined): string | undefined;
/**
* Resolves the UI language for an incoming server request.
*
* Priority:
* 0. the URL locale prefix (`routing: "prefix"`) — the URL is the source of
* truth and wins over everything, with no redirect;
* 1. the `lang` cookie — a language the user manually selected;
* 2. the `Accept-Language` header (when `autoDetect` is enabled) — but only
* when the detected language is actually registered, so we never switch to
* a locale we have no dictionary for. A region-qualified header (`en-US`)
* matches an exact registration first, then its base language (`en`);
* 3. `fallbackLang`.
*/
protected resolveRequestLang(cookieLang: string | undefined, headerLang: string | undefined, urlLocale?: string): string;
protected readonly onStart: import("alepha").HookPrimitive<"start">;
protected refreshLocale(): void;
/**
* Activates a language: lazily loads its dictionaries (browser), updates the
* lang state, and refreshes the locale-bound formatters. Does NOT persist a
* cookie or navigate — that is the caller's concern.
*/
protected applyLang: (lang: string) => Promise<void>;
setLang: (lang: string) => Promise<void>;
protected readonly mutate: import("alepha").HookPrimitive<"state:mutate">;
get fallbackLang(): string;
get lang(): string;
translate: (key: string, args?: string[]) => string;
readonly l: (value: I18nLocalizeType, options?: I18nLocalizeOptions) => string | number;
/**
* Look up `key` in the registered dictionaries. The `(string & {})` arm
* keeps autocomplete for the typed dictionary keys while allowing shared
* library components to pass arbitrary string keys (with a `default`
* fallback) without casting to `as never`.
*/
readonly tr: (key: keyof ServiceDictionary<S>[K] | (string & {}), options?: {
args?: string[];
default?: string;
}) => string;
protected render(item: string, args: string[]): string;
}
type I18nLocalizeType = string | number | Date | DateTime | TypeBoxError;
interface I18nLocalizeOptions {
/**
* Options for number formatting (when value is a number)
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat
*/
number?: Intl.NumberFormatOptions;
/**
* Options for date formatting (when value is a Date or DateTime)
* Can be:
* - A dayjs format string (e.g., "LLL", "YYYY-MM-DD", "dddd, MMMM D YYYY")
* - "fromNow" for relative time (e.g., "2 hours ago")
* - Intl.DateTimeFormatOptions for native formatting
* @see https://day.js.org/docs/en/display/format
* @see https://day.js.org/docs/en/display/from-now
*/
date?: string | "fromNow" | Intl.DateTimeFormatOptions;
/**
* Timezone to display dates in (when value is a Date or DateTime)
* Uses IANA timezone names (e.g., "America/New_York", "Europe/Paris", "Asia/Tokyo")
* @see https://day.js.org/docs/en/timezone/timezone
*/
timezone?: string;
}
//#endregion
//#region ../../src/react/i18n/primitives/$dictionary.d.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);
* ```
*/
declare const $dictionary: {
<T extends Record<string, string>>(options: DictionaryPrimitiveOptions<T>): DictionaryPrimitive<T>;
[KIND]: typeof DictionaryPrimitive;
};
interface DictionaryPrimitiveOptions<T extends Record<string, string>> {
lang?: string;
name?: string;
lazy: () => Async<{
default: T;
}>;
}
declare class DictionaryPrimitive<T extends Record<string, string>> extends Primitive<DictionaryPrimitiveOptions<T>> {
protected provider: I18nProvider<object, never>;
protected onInit(): void;
}
//#endregion
//#region ../../src/react/i18n/hooks/useI18n.d.ts
/**
* Hook to access the i18n service.
*/
declare const useI18n: <S extends object, K extends keyof ServiceDictionary<S>>() => I18nProvider<S, K>;
type ServiceDictionary<T extends object> = { [K in keyof T]: T[K] extends DictionaryPrimitive<infer U> ? U : never; };
//#endregion
//#region ../../src/react/i18n/index.d.ts
declare module "alepha" {
interface State {
"alepha.react.i18n.lang"?: string;
}
}
/**
* Multi-language support.
*
* **Features:**
* - Translation loading
* - Locale detection
* - Pluralization
*
* @module alepha.react.i18n
*/
declare const AlephaReactI18n: import("alepha").Service<import("alepha").Module>;
//#endregion
export { $dictionary, AlephaReactI18n, DictionaryPrimitive, DictionaryPrimitiveOptions, I18nLocalizeOptions, I18nLocalizeType, I18nProvider, Localize, type LocalizeProps, ServiceDictionary, Tr, Translate, type TranslateProps, useI18n };
//# sourceMappingURL=index.d.ts.map