/**
* tina4js/i18n — Internationalization and localization. Reactive, zero deps.
*
* The active locale is a SIGNAL. t() and the Intl-backed formatters read it,
* so when you switch locale every translated string and every formatted
* number/date re-renders in place — as long as you use them in the reactive
* function form inside a template:
*
* html`
${() => i18n.t('greeting')}
`
* html`${() => i18n.currency(19.99, 'USD')}
`
* i18n.setLocale('fr'); // both update, no reload
*
* Formatting is delegated to the browser's native Intl APIs, so there is no
* locale data to ship. Translations are key-based JSON bundles, mirroring the
* backend tina4 I18n API (t / setLocale / getLocale / addMessages /
* availableLocales) so the frontend and backend speak the same shape.
*/
import { type Signal } from '../core/signal';
/** A bundle of messages for one locale. Nested objects are allowed. */
export type Messages = Record;
/** Message bundles keyed by locale code, e.g. { en: {...}, fr: {...} }. */
export type LocaleMessages = Record;
export interface I18nOptions {
/** Active locale. Default: the browser's navigator.language, else 'en'. */
locale?: string;
/** Locale used when a key is missing in the active locale. Default: the initial locale. */
fallbackLocale?: string;
/** Initial bundles keyed by locale. Nested objects are flattened (dot-path + leaf alias). */
messages?: LocaleMessages;
/** Extra base codes (e.g. 'ar') to treat as right-to-left, on top of the built-in set. */
rtlLocales?: string[];
}
export interface I18n {
/** The active locale as a reactive signal. Set `.value` or call setLocale(). */
readonly locale: Signal;
/** Translate a key, with optional {placeholder} interpolation. Reactive when read in a function block. */
t(key: string, params?: Record): string;
/** Switch the active locale (updates the signal, so dependents re-render). */
setLocale(locale: string): void;
/** The active locale code. */
getLocale(): string;
/** Merge a bundle into a locale (nested objects flattened). Existing keys are overwritten. */
addMessages(locale: string, messages: Messages): void;
/** True if any messages are loaded for the locale. */
hasLocale(locale: string): boolean;
/** Sorted list of locale codes that have messages loaded. */
availableLocales(): string[];
/** Fetch a JSON bundle from a URL and merge it into the locale. */
loadMessages(locale: string, url: string): Promise;
/** Format a number for the active locale via Intl.NumberFormat. */
number(value: number, options?: Intl.NumberFormatOptions): string;
/** Format a currency amount for the active locale. */
currency(value: number, currency: string, options?: Intl.NumberFormatOptions): string;
/** Format a date for the active locale via Intl.DateTimeFormat. Accepts Date, epoch ms, or a parseable string. */
date(value: Date | number | string, options?: Intl.DateTimeFormatOptions): string;
/** Format a relative time (e.g. -1, 'day' -> "yesterday") via Intl.RelativeTimeFormat. */
relativeTime(value: number, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions): string;
/** True when the active locale is right-to-left. Reactive when read in a function block. */
isRTL(): boolean;
/** "rtl" or "ltr" for the active locale — bind to a container's `dir`. */
dir(): 'rtl' | 'ltr';
}
/**
* Create an isolated i18n instance. Most apps use the default `i18n` singleton,
* but multiple instances are supported (e.g. per-widget or for testing).
*/
export declare function createI18n(options?: I18nOptions): I18n;
/** The default i18n instance. Configure with i18n.addMessages(...) / i18n.setLocale(...). */
export declare const i18n: I18n;
/** Translate via the default instance. Reactive when read in a function block. */
export declare function t(key: string, params?: Record): string;
/** Switch the default instance's locale. */
export declare function setLocale(locale: string): void;
/** The default instance's active locale. */
export declare function getLocale(): string;
//# sourceMappingURL=i18n.d.ts.map