import * as i0 from '@angular/core'; import { InjectionToken, Signal, PipeTransform, EnvironmentProviders, Provider } from '@angular/core'; import { Observable } from 'rxjs'; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** Translation catalog — flat or nested record of strings. */ interface WrI18nCatalog { readonly [key: string]: string | WrI18nCatalog; } /** Parameters passed to interpolation — coerced to strings via `String(v)`. */ type WrI18nParams = Readonly>; /** Hook called once on every key that resolves to nothing. */ type WrI18nMissingHandler = (key: string, locale: string) => string; /** User-facing config for {@link provideWrI18n}. */ interface WrI18nConfig { /** BCP-47 tag used until the user calls `setLocale`. @default 'en' */ readonly defaultLocale?: string; /** Whitelisted locales — `setLocale` ignores anything outside this list. */ readonly availableLocales?: readonly string[]; /** * Storage key for persisting the active locale (via `WrStorage`). * Set to `null` to disable persistence. @default 'wr:i18n:locale' */ readonly storageKey?: string | null; /** Called when a key is missing. Default returns the key itself. */ readonly missingHandler?: WrI18nMissingHandler; } /** Resolved config — every field non-optional. @internal */ interface WrI18nConfigResolved { readonly defaultLocale: string; readonly availableLocales: readonly string[]; readonly storageKey: string | null; readonly missingHandler: WrI18nMissingHandler; } declare const DEFAULT_WR_I18N_CONFIG: WrI18nConfigResolved; declare const WR_I18N_CONFIG: InjectionToken; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Reactive i18n service. Holds: * * - the active locale as a `Signal` * - per-`(locale, scope)` catalogs in a `Map` (loaded once, then cached) * - a per-locale signal counter so every `translate()` reading the signal * re-evaluates the moment a new catalog finishes loading * * Translations are looked up scope-first, then root. `t('forms.save', { ... })` * with `scope: 'forms'` will try the scoped catalog before falling back to * `forms.save` in the root catalog — useful for per-feature overrides. * * @example * ```ts * const i18n = inject(WrI18n); * i18n.use('ru'); // switch locale * i18n.t('cart.checkout'); // → 'Оформить заказ' * i18n.t('greeting', { name: 'Ada' }); // → 'Hello, Ada!' * * effect(() => console.log(i18n.translate('hi')())); // re-runs on locale change * ``` * * @see https://ngwr.dev/services/i18n */ declare class WrI18n { private readonly config; private readonly loader; private readonly storage; /** Per-(locale,scope) catalogs, populated by `loadCatalog`. @internal */ private readonly catalogs; /** Bumped after each catalog write so reactive translates recompute. @internal */ private readonly revision; /** In-flight load promises — dedupes parallel `t()` callers. @internal */ private readonly inflight; /** Registered scopes — auto-loaded whenever the locale changes. @internal */ private readonly scopes; /** Active locale. Writes go through `use()` so storage stays in sync. */ private readonly _locale; readonly locale: Signal; constructor(); /** Switch active locale. Ignored when not whitelisted. */ use(locale: string): void; /** Available locales — pass-through from config. */ available(): readonly string[]; /** * Register a scope so its catalog loads alongside the root one. Idempotent. * Returns a promise resolving once the current locale's scope catalog is in * the cache — handy for feature `canActivate` guards. */ registerScope(scope: string): Promise; /** * Eager translate — returns the current value or the missing-handler * fallback. Does NOT auto-load missing catalogs; combine with the * reactive `translate(...)` if you want load-on-demand. */ t(key: string, params?: WrI18nParams, scope?: string): string; /** Reactive translate — re-evaluates on locale or catalog updates. */ translate(key: string, params?: WrI18nParams, scope?: string): Signal; private initialLocale; private loadCatalog; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Translate a key. Impure — re-evaluates on every CD so locale switches * and catalog loads propagate without a manual refresh. * * @example * ```html *

{{ 'home.title' | wrT }}

*

{{ 'greeting' | wrT: { name: user().name } }}

* * ``` */ declare class WrTPipe implements PipeTransform { private readonly i18n; transform(key: string, params?: WrI18nParams | null, scope?: string): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵpipe: i0.ɵɵPipeDeclaration; } /** * Attribute directive that sets `textContent` of its host to the translation * of the bound key. Reactive — re-renders on locale + catalog changes. * * @example * ```html * * * * ``` */ declare class WrTDirective { /** Translation key. Required. */ readonly wrT: i0.InputSignal; /** Interpolation params for `{{name}}` tokens. */ readonly wrTParams: i0.InputSignal> | null>; /** Optional scope — scoped lookup first, then root fallback. */ readonly wrTScope: i0.InputSignal; private readonly host; private readonly i18n; private readonly text; constructor(); static ɵfac: i0.ɵɵFactoryDeclaration; static ɵdir: i0.ɵɵDirectiveDeclaration; } /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Loads a catalog for a `(locale, scope)` pair. `scope` is `null` for the * root catalog. Implementations may return the catalog synchronously * (via `of(...)`) for static catalogs or asynchronously (via HTTP) for * lazy fetches. */ interface WrI18nLoader { load(locale: string, scope: string | null): Observable; } declare const WR_I18N_LOADER: InjectionToken; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** Root catalogs keyed by locale: `{ en: catalog, ru: catalog, … }`. */ type WrI18nStaticCatalogs = Readonly>; /** Per-scope catalogs: `{ checkout: { en: catalog, ru: catalog }, … }`. */ type WrI18nStaticScopedCatalogs = Readonly>; /** * Loader for catalogs already in memory (imported from JSON or generated). * * - Pass `catalogs` for the root catalog of every locale. * - Pass `scopes` if you ship per-feature catalogs the loader should serve * to `WrI18n.registerScope(name)` calls. * * Missing locale or scope resolves to `{}` — the missing-key handler then * decides what to render. */ declare class WrI18nStaticLoader implements WrI18nLoader { private readonly catalogs; private readonly scopes; constructor(catalogs: WrI18nStaticCatalogs, scopes?: WrI18nStaticScopedCatalogs); load(locale: string, scope: string | null): Observable; } /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** Configuration for {@link WrI18nHttpLoader}. */ interface WrI18nHttpLoaderConfig { /** * URL template. Tokens: * - `{locale}` — required, BCP-47 tag (e.g. `en`). * - `{scope}` — optional, scope name. Use the `rootPath` if you need a * different path entirely for the root catalog. * * @example * ```ts * { path: '/assets/i18n/{locale}.json' } // root only * { path: '/assets/i18n/{scope}/{locale}.json', * rootPath: '/assets/i18n/{locale}.json' } // root + scopes * ``` */ readonly path: string; /** Path template for the root catalog. Defaults to `path`. */ readonly rootPath?: string; } /** * Loader that fetches catalogs via `HttpClient`. Failures resolve to `{}` * (logged once at the service layer) so a missing file never throws into * user code. */ declare class WrI18nHttpLoader implements WrI18nLoader { private readonly config; private readonly http; constructor(config: WrI18nHttpLoaderConfig); load(locale: string, scope: string | null): Observable; } /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Configure {@link WrI18n}. Either pass a `loader` directly, or use the * `provideWrI18nHttpLoader` / `provideWrI18nStaticLoader` helpers in the * same providers array. */ interface ProvideWrI18nOptions extends WrI18nConfig { readonly loader?: WrI18nLoader; } declare function provideWrI18n(options?: ProvideWrI18nOptions): EnvironmentProviders; /** * Provide a static loader — catalogs already in memory. * * @param catalogs Root catalogs keyed by locale. * @param scopes Optional per-scope catalogs served to `registerScope(name)`. */ declare function provideWrI18nStaticLoader(catalogs: WrI18nStaticCatalogs, scopes?: WrI18nStaticScopedCatalogs): Provider; /** Provide an HTTP loader — catalogs fetched from URLs. Requires `provideHttpClient`. */ declare function provideWrI18nHttpLoader(config: WrI18nHttpLoaderConfig): Provider; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Helper for component default text. Returns a reactive string that: * * 1. Prefers the consumer's override (an `input()` value). * 2. Falls back to the i18n catalog under `key` — re-renders on locale * change so a switcher updates the DOM live. * 3. Falls back to `fallback` when no `WrI18n` is provided OR the catalog * is missing the key. * * Components don't need a hard dependency on `provideWrI18n` — without it, * the fallback is returned and everything still works. * * @example * ```ts * readonly emptyText = input(null); * protected readonly empty = useI18nText(this.emptyText, 'table.empty', 'No data'); * * // In template:
{{ empty() }}
* ``` */ declare function useI18nText(binding: Signal, key: string, fallback: string): Signal; /** * Like {@link useI18nText} but takes a literal value (not a Signal) — for * computed `aria-label`s that already mix a static piece with a dynamic * value. Returns the resolved string once, at injection time. */ declare function readI18nText(key: string, fallback: string): string; /** * Build a per-call formatter for parametrized labels (e.g. ARIA labels * that interpolate a per-row value: `"Remove {{label}}"`). Returns a * function the template calls with the params for the current item. * * The returned function: * - Re-resolves the i18n catalog on every call (live locale switches just * work — re-rendered templates pick up new strings). * - Falls back to the literal `fallback` template with the same * `{{name}}` syntax when no `WrI18n` provider is present, or when the * key is missing. * * Use this for labels that vary per row. For static labels, prefer * {@link useI18nText} or {@link readI18nText}. * * @example * ```ts * protected readonly removeChipLabel = useI18nFormatter('select.removeItem', 'Remove {{label}}'); * * // In template: * // [attr.aria-label]="removeChipLabel({ label: chip.label })" * ``` */ declare function useI18nFormatter(key: string, fallback: string): (params?: WrI18nParams) => string; export { DEFAULT_WR_I18N_CONFIG, WR_I18N_CONFIG, WR_I18N_LOADER, WrI18n, WrI18nHttpLoader, WrI18nStaticLoader, WrTDirective, WrTPipe, provideWrI18n, provideWrI18nHttpLoader, provideWrI18nStaticLoader, readI18nText, useI18nFormatter, useI18nText }; export type { ProvideWrI18nOptions, WrI18nCatalog, WrI18nConfig, WrI18nConfigResolved, WrI18nHttpLoaderConfig, WrI18nLoader, WrI18nMissingHandler, WrI18nParams, WrI18nStaticCatalogs, WrI18nStaticScopedCatalogs };