ngx-kit 9.0.0 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/drag-resize/README.md +6 -5
- package/fesm2022/ngx-kit-drag-resize.mjs +413 -161
- package/fesm2022/ngx-kit-drag-resize.mjs.map +1 -1
- package/fesm2022/ngx-kit-lazy-i18n.mjs +141 -53
- package/fesm2022/ngx-kit-lazy-i18n.mjs.map +1 -1
- package/lazy-i18n/README.md +86 -20
- package/package.json +1 -1
- package/types/ngx-kit-drag-resize.d.ts +13 -4
- package/types/ngx-kit-lazy-i18n.d.ts +83 -15
package/lazy-i18n/README.md
CHANGED
|
@@ -17,21 +17,22 @@ Flat keys, route-level scopes, pipe, directives, fallbacks and a key extractor C
|
|
|
17
17
|
|
|
18
18
|
1. [Install](#install)
|
|
19
19
|
2. [Quick start](#quick-start)
|
|
20
|
-
3. [
|
|
21
|
-
4. [
|
|
22
|
-
5. [
|
|
23
|
-
6. [
|
|
24
|
-
7. [
|
|
25
|
-
8. [
|
|
26
|
-
9. [
|
|
27
|
-
10. [
|
|
28
|
-
11. [
|
|
29
|
-
12. [
|
|
30
|
-
13. [
|
|
31
|
-
14. [
|
|
32
|
-
15. [
|
|
33
|
-
16. [
|
|
34
|
-
17. [
|
|
20
|
+
3. [Deferred configuration (languages from the backend)](#deferred-configuration-languages-from-the-backend)
|
|
21
|
+
4. [Concepts](#concepts)
|
|
22
|
+
5. [Using translations](#using-translations)
|
|
23
|
+
6. [Scopes and routing](#scopes-and-routing)
|
|
24
|
+
7. [Language switching](#language-switching)
|
|
25
|
+
8. [Fallbacks and missing keys](#fallbacks-and-missing-keys)
|
|
26
|
+
9. [Interpolation, plurals and ICU](#interpolation-plurals-and-icu)
|
|
27
|
+
10. [Loaders](#loaders)
|
|
28
|
+
11. [Key extractor CLI](#key-extractor-cli)
|
|
29
|
+
12. [Configuration reference](#configuration-reference)
|
|
30
|
+
13. [API reference](#api-reference)
|
|
31
|
+
14. [Testing your app](#testing-your-app)
|
|
32
|
+
15. [Performance notes](#performance-notes)
|
|
33
|
+
16. [Migrating from Transloco](#migrating-from-transloco)
|
|
34
|
+
17. [Limitations](#limitations)
|
|
35
|
+
18. [Developing this library](#developing-this-library)
|
|
35
36
|
|
|
36
37
|
---
|
|
37
38
|
|
|
@@ -116,6 +117,62 @@ export class RequestsComponent {
|
|
|
116
117
|
}
|
|
117
118
|
```
|
|
118
119
|
|
|
120
|
+
## Deferred configuration (languages from the backend)
|
|
121
|
+
|
|
122
|
+
Often the list of languages, the default language and the user's saved language only exist **after** your own
|
|
123
|
+
`APP_INITIALIZER` has talked to the backend. Do not try to build the config earlier (no `setTimeout`, no mutating
|
|
124
|
+
the config token, no async `useFactory`): provide the library **without** languages and finish the setup with
|
|
125
|
+
`I18nService.init()` when you know them.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
// app.config.ts
|
|
129
|
+
provideHttpClient(),
|
|
130
|
+
provideI18n({ fallbackLangs: ['fa'] }), // no langs/defaultLang -> no automatic initializer
|
|
131
|
+
provideAppInitializer(() => AppInitializer()),
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
// app-initializer.ts
|
|
136
|
+
export async function AppInitializer(): Promise<void> {
|
|
137
|
+
const http = inject(HttpClient);
|
|
138
|
+
const platformLocation = inject(PlatformLocation);
|
|
139
|
+
const i18n = inject(I18nService);
|
|
140
|
+
inject(ColorSchemaService).load();
|
|
141
|
+
|
|
142
|
+
// 1) appconfig.json 2) /api/Common/InitialApp (as you do today)
|
|
143
|
+
const config = await firstValueFrom(http.get<any>(configUrl(platformLocation)));
|
|
144
|
+
AppConst.apiUrl = config.apiUrl; /* … */
|
|
145
|
+
const resp = await firstValueFrom(http.get<InitialAppDto>(AppConst.apiUrl + '/api/Common/InitialApp'));
|
|
146
|
+
AppConst.languageList = resp.languages ?? [];
|
|
147
|
+
AppConst.defaultLang = resp.defaultLang ?? 'fa';
|
|
148
|
+
|
|
149
|
+
// 3) finish the i18n setup and load the first language. AWAIT it: the app starts when translations are ready.
|
|
150
|
+
await i18n.init({
|
|
151
|
+
langs: AppConst.languageList.map((l) => l.culture),
|
|
152
|
+
defaultLang: AppConst.defaultLang,
|
|
153
|
+
baseUrl: AppConst.apiUrl, // read at request time, so a value known only now is fine
|
|
154
|
+
lang: AppConst.currentLanguage, // optional: user's saved language; ignored if not in `langs`
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
What `init()` does: merges the options into the live config (`configure()`), picks the language
|
|
160
|
+
(`lang` if supported, otherwise stored > browser (opt-in) > `defaultLang`), downloads the global file, every scope
|
|
161
|
+
registered so far and the fallback languages, and only then activates the language. It rejects if loading fails, so
|
|
162
|
+
you can catch it in the initializer and show an error page.
|
|
163
|
+
|
|
164
|
+
Notes:
|
|
165
|
+
|
|
166
|
+
- `loader` and `autoInit` can only be set in `provideI18n()`. Everything else can be changed later with
|
|
167
|
+
`i18n.configure({...})`; files that are already downloaded stay cached.
|
|
168
|
+
- When `langs` **and** `defaultLang` are given to `provideI18n()`, an initializer is added automatically
|
|
169
|
+
(`autoInit` defaults to `true`). Use `autoInit: false` if you prefer to call `init()` yourself.
|
|
170
|
+
- `i18n.langs` is a **signal** (`i18n.langs()`) because the list can arrive after startup. `i18n.ready()` becomes
|
|
171
|
+
`true` after the first language is active.
|
|
172
|
+
- Scopes registered before `init()` (for example by an early service) are remembered and loaded by `init()`.
|
|
173
|
+
`whenReady()` and `i18nReadyGuard` also wait for an in-flight `init()` / `use()`.
|
|
174
|
+
- Do not call `use()` without awaiting it inside an initializer: the app would start before the files arrive.
|
|
175
|
+
|
|
119
176
|
## Concepts
|
|
120
177
|
|
|
121
178
|
| Term | Meaning |
|
|
@@ -250,6 +307,11 @@ Use a real ICU library (for example `intl-messageformat`) inside `transpile` for
|
|
|
250
307
|
|
|
251
308
|
The default `HttpI18nLoader` uses `HttpClient`, so your interceptors (auth, base URL, retry) apply.
|
|
252
309
|
|
|
310
|
+
URLs are built as `{baseUrl}/{scope}/{lang}{fileExtension}` (global file: `{baseUrl}/{lang}{fileExtension}`).
|
|
311
|
+
The builder is safe by construction: a missing scope never becomes `undefined`, repeated or trailing slashes
|
|
312
|
+
are collapsed (`'https://api.x.com/'` + no scope -> `https://api.x.com/fa.json`), and the extension may be written
|
|
313
|
+
with or without the dot. `buildI18nUrl()` is exported if you need the same logic in a custom loader.
|
|
314
|
+
|
|
253
315
|
```ts
|
|
254
316
|
provideI18n({
|
|
255
317
|
…,
|
|
@@ -333,15 +395,16 @@ Add to `package.json` scripts: `"i18n": "ngx-lazy-i18n-extract"`, `"i18n:check":
|
|
|
333
395
|
|
|
334
396
|
| Option | Type | Default | Description |
|
|
335
397
|
|---|---|---|---|
|
|
336
|
-
| `langs` | `string[]` | required | Supported languages. |
|
|
337
|
-
| `defaultLang` | `string` | required | Used when nothing is stored or detected. |
|
|
398
|
+
| `langs` | `string[]` | required before first activation | Supported languages. May be supplied later with `init()`. |
|
|
399
|
+
| `defaultLang` | `string` | required before first activation | Used when nothing is stored or detected. May be supplied later. |
|
|
400
|
+
| `autoInit` | `boolean` | `true` if `langs` and `defaultLang` are given | Add an APP_INITIALIZER that activates the initial language. Provide-time only. |
|
|
338
401
|
| `fallbackLangs` | `string[]` | `[]` | Languages tried, in order, for missing/empty keys. |
|
|
339
402
|
| `missing` | `'key' \| 'empty' \| (key, lang) => string` | `'key'` | What to render for a missing key. |
|
|
340
403
|
| `warnMissing` | `boolean` | `isDevMode()` | Log each missing key once. |
|
|
341
404
|
| `transpile` | `(value, params, lang) => string` | built-in `{{ }}` | Custom message formatter. |
|
|
342
405
|
| `loader` | `Type<I18nLoader>` | `HttpI18nLoader` | Custom loader class. |
|
|
343
406
|
| `baseUrl` | `string` | `'/i18n'` | HTTP loader base. |
|
|
344
|
-
| `fileExtension` | `string` | `''` | HTTP loader extension
|
|
407
|
+
| `fileExtension` | `string` | `'.json'` | HTTP loader extension; `''` for none. |
|
|
345
408
|
| `url` | `(lang, scope?) => string` | none | HTTP loader full URL control. |
|
|
346
409
|
| `retries` | `number` | `1` | Retries per failed request (250 ms delay). |
|
|
347
410
|
| `storageKey` | `string \| null` | `'lazy-i18n.lang'` | Persist language; `null` disables. |
|
|
@@ -363,7 +426,10 @@ Add to `package.json` scripts: `"i18n": "ngx-lazy-i18n-extract"`, `"i18n:check":
|
|
|
363
426
|
| `lang: Signal<string>` | Active language. |
|
|
364
427
|
| `dir: Signal<'rtl' \| 'ltr'>` | Direction for the active language. |
|
|
365
428
|
| `revision: Signal<number>` | Changes on every language/dictionary change. |
|
|
366
|
-
| `langs: readonly string[]
|
|
429
|
+
| `langs: Signal<readonly string[]>` | Supported languages (reactive; may arrive after startup). |
|
|
430
|
+
| `ready: Signal<boolean>` | `true` after the first language is active. |
|
|
431
|
+
| `init({ langs, defaultLang, baseUrl, lang, … })` | Complete the config and activate the first language. Use in your own initializer. |
|
|
432
|
+
| `configure(patch)` | Change options after startup (not `loader`/`autoInit`). |
|
|
367
433
|
| `t(key, params?)` | Translate (reactive). |
|
|
368
434
|
| `instant(key, params?)` | Translate (non-reactive). |
|
|
369
435
|
| `select(key, params?)` | `Signal<string>`; `params` may be a function. |
|
|
@@ -371,7 +437,7 @@ Add to `package.json` scripts: `"i18n": "ngx-lazy-i18n-extract"`, `"i18n:check":
|
|
|
371
437
|
| `use(lang)` | Load everything, then activate. |
|
|
372
438
|
| `preload(lang)` | Download without activating. |
|
|
373
439
|
| `registerScope(scope)` | Register and start loading a scope. |
|
|
374
|
-
| `whenReady()` | Resolves when all registered scopes are
|
|
440
|
+
| `whenReady()` | Resolves when all registered scopes and any in-flight `init()`/`use()` are done. Never rejects. |
|
|
375
441
|
| `setTranslation(lang, dict, merge = true)` | Inject translations manually. |
|
|
376
442
|
| `detectInitialLang()` | Stored, browser (opt-in) or default. |
|
|
377
443
|
|
package/package.json
CHANGED
|
@@ -268,6 +268,8 @@ declare class DragRef<T = unknown> {
|
|
|
268
268
|
private sourceDisplay;
|
|
269
269
|
private sourcePointerEvents;
|
|
270
270
|
private sourceTransition;
|
|
271
|
+
private sourceWillChange;
|
|
272
|
+
private sourceTransform;
|
|
271
273
|
/** True while a drop-list drag (body preview + placeholder) is in progress. Free drag: always false. */
|
|
272
274
|
private listDrag;
|
|
273
275
|
private cachedLists;
|
|
@@ -399,7 +401,6 @@ declare class NgxDraggable<T = unknown> implements OnInit, OnDestroy, AfterConte
|
|
|
399
401
|
readonly dragEnd: _angular_core.OutputEmitterRef<IPosition>;
|
|
400
402
|
readonly _ref: DragRef<T>;
|
|
401
403
|
readonly dragging: _angular_core.WritableSignal<boolean>;
|
|
402
|
-
private readonly doc;
|
|
403
404
|
private readonly service;
|
|
404
405
|
private readonly scroller;
|
|
405
406
|
private down;
|
|
@@ -444,7 +445,7 @@ declare class NgxDraggable<T = unknown> implements OnInit, OnDestroy, AfterConte
|
|
|
444
445
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgxDraggable<any>, "[NgxDraggable],[ngxDraggable]", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "boundary": { "alias": "boundary"; "required": false; "isSignal": true; }; "dragRootElement": { "alias": "dragRootElement"; "required": false; "isSignal": true; }; "dragHandle": { "alias": "dragHandle"; "required": false; "isSignal": true; }; "lockAxis": { "alias": "lockAxis"; "required": false; "isSignal": true; }; "dragThreshold": { "alias": "dragThreshold"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; "autoScroll": { "alias": "autoScroll"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; }; }, { "disabled": "disabledChange"; "dragRootElement": "dragRootElementChange"; "dragHandle": "dragHandleChange"; "dragStart": "dragStart"; "dragMove": "dragMove"; "dragEnd": "dragEnd"; }, ["customPreview"], never, true, never>;
|
|
445
446
|
}
|
|
446
447
|
|
|
447
|
-
declare class NgxResizable {
|
|
448
|
+
declare class NgxResizable implements OnDestroy {
|
|
448
449
|
private readonly el;
|
|
449
450
|
disabled: _angular_core.ModelSignal<boolean>;
|
|
450
451
|
readonly minWidth: _angular_core.ModelSignal<number>;
|
|
@@ -472,11 +473,18 @@ declare class NgxResizable {
|
|
|
472
473
|
private beforeHeight;
|
|
473
474
|
private beforeTransform;
|
|
474
475
|
private pointerId;
|
|
476
|
+
private startWidth;
|
|
477
|
+
private startHeight;
|
|
478
|
+
private removeDocumentListeners;
|
|
479
|
+
private readonly renderer;
|
|
475
480
|
constructor(el: ElementRef<HTMLElement>);
|
|
481
|
+
ngOnDestroy(): void;
|
|
476
482
|
onPointerDown(e: PointerEvent): void;
|
|
477
483
|
onPointerMove(e: PointerEvent): void;
|
|
478
484
|
onPointerUp(e: PointerEvent): void;
|
|
479
485
|
onDocumentKeyDown(e: KeyboardEvent): void;
|
|
486
|
+
private onPointerCancel;
|
|
487
|
+
private restoreBeforeResize;
|
|
480
488
|
onHandleKeyDown(e: KeyboardEvent): void;
|
|
481
489
|
private calculate;
|
|
482
490
|
private apply;
|
|
@@ -597,9 +605,9 @@ declare function clampResizeWithinBoundary(boundaryRect: DOMRect | undefined, st
|
|
|
597
605
|
top: number;
|
|
598
606
|
};
|
|
599
607
|
/** Current page zoom level (1 = 100%). Falls back to devicePixelRatio pre visualViewport. */
|
|
600
|
-
declare function getPageZoom(): number;
|
|
608
|
+
declare function getPageZoom(element?: HTMLElement): number;
|
|
601
609
|
/** Adjusts a raw pointer-derived value for the current page zoom level. */
|
|
602
|
-
declare function adjustForZoom(value: number): number;
|
|
610
|
+
declare function adjustForZoom(value: number, element?: HTMLElement): number;
|
|
603
611
|
|
|
604
612
|
/**
|
|
605
613
|
* Auto-scrolls the nearest scrollable ancestor (or window) while the pointer
|
|
@@ -609,6 +617,7 @@ declare function adjustForZoom(value: number): number;
|
|
|
609
617
|
declare class AutoScroller {
|
|
610
618
|
private raf;
|
|
611
619
|
private container;
|
|
620
|
+
private win?;
|
|
612
621
|
private speed;
|
|
613
622
|
private onTick?;
|
|
614
623
|
private readonly edge;
|
|
@@ -15,10 +15,16 @@ interface I18nLoader {
|
|
|
15
15
|
/** `scope === undefined` means the global file. */
|
|
16
16
|
load(lang: string, scope?: string): Observable<Dictionary> | Promise<Dictionary>;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Every option is optional so the library can be provided at startup and completed later
|
|
20
|
+
* (for example after your own APP_INITIALIZER has fetched the language list from the backend):
|
|
21
|
+
* see `I18nService.init()` / `I18nService.configure()`.
|
|
22
|
+
*/
|
|
23
|
+
interface I18nConfig {
|
|
24
|
+
/** All supported languages. Required before the first language is activated. */
|
|
25
|
+
langs?: string[];
|
|
26
|
+
/** Language used when nothing is stored or detected. Required before the first language is activated. */
|
|
27
|
+
defaultLang?: string;
|
|
22
28
|
/** Looked up (in order) when a key is empty/missing in the active language. */
|
|
23
29
|
fallbackLangs?: string[];
|
|
24
30
|
/** Default `'key'` (returns the key itself). */
|
|
@@ -27,11 +33,11 @@ declare class I18nConfig {
|
|
|
27
33
|
warnMissing?: boolean;
|
|
28
34
|
/** Replace the default `{{ name }}` interpolation (ICU, plurals, ...). */
|
|
29
35
|
transpile?: Transpiler;
|
|
30
|
-
/** Custom loader class (must be `@Injectable({providedIn:'root'})` or constructible without args). Default: HTTP. */
|
|
36
|
+
/** Custom loader class (must be `@Injectable({providedIn:'root'})` or constructible without args). Default: HTTP. Provide-time only. */
|
|
31
37
|
loader?: Type<I18nLoader>;
|
|
32
|
-
/** Default HTTP loader: base URL. Default `'/i18n'` -> `/i18n/fa`, `/i18n/setting/fa`. */
|
|
38
|
+
/** Default HTTP loader: base URL. Default `'/i18n'` -> `/i18n/fa.json`, `/i18n/setting/fa.json`. Slashes are normalised. */
|
|
33
39
|
baseUrl?: string;
|
|
34
|
-
/** Default HTTP loader: file extension appended to the URL, e.g. `'.json'`. Default `'.json'
|
|
40
|
+
/** Default HTTP loader: file extension appended to the URL, e.g. `'.json'`. Default `'.json'`; use `''` for none. */
|
|
35
41
|
fileExtension?: string;
|
|
36
42
|
/** Default HTTP loader: full control over the URL. */
|
|
37
43
|
url?: (lang: string, scope?: string) => string;
|
|
@@ -43,7 +49,23 @@ declare class I18nConfig {
|
|
|
43
49
|
detectBrowserLang?: boolean;
|
|
44
50
|
/** Keep `<html lang dir>` in sync. Default `true`. */
|
|
45
51
|
manageDocument?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Activate the initial language in an APP_INITIALIZER created by `provideI18n()`.
|
|
54
|
+
* Default: `true` when both `langs` and `defaultLang` are given to `provideI18n()`, otherwise `false`
|
|
55
|
+
* (then you call `I18nService.init()` yourself, typically from your own initializer).
|
|
56
|
+
* Provide-time only.
|
|
57
|
+
*/
|
|
58
|
+
autoInit?: boolean;
|
|
46
59
|
}
|
|
60
|
+
/** Options that can be changed after the app has started. */
|
|
61
|
+
type I18nRuntimeConfig = Omit<I18nConfig, 'loader' | 'autoInit'>;
|
|
62
|
+
/** `I18nService.init()` options: runtime config + the language to start with. */
|
|
63
|
+
interface I18nInitOptions extends I18nRuntimeConfig {
|
|
64
|
+
/** Preferred starting language (e.g. the user's saved language from the backend). Ignored if not in `langs`. */
|
|
65
|
+
lang?: string;
|
|
66
|
+
}
|
|
67
|
+
/** Defaults applied by `provideI18n()`. */
|
|
68
|
+
declare const I18N_DEFAULTS: I18nConfig;
|
|
47
69
|
declare const I18N_CONFIG: InjectionToken<I18nConfig>;
|
|
48
70
|
declare const I18N_LOADER: InjectionToken<I18nLoader>;
|
|
49
71
|
|
|
@@ -114,8 +136,21 @@ declare function flatten(dict: Dictionary, target?: Map<string, string>, onConfl
|
|
|
114
136
|
declare function interpolate(text: string, params?: Params): string;
|
|
115
137
|
/** Identity function the extractor recognises: `const k = marker('orders.title')`. */
|
|
116
138
|
declare function marker<T extends string>(key: T): T;
|
|
139
|
+
/**
|
|
140
|
+
* Build `{base}/{scope}/{lang}{ext}` without ever producing `undefined`, `//` or a trailing slash problem:
|
|
141
|
+
* ("/i18n", undefined, "fa", ".json") -> "/i18n/fa.json"
|
|
142
|
+
* ("https://x.com/", "setting", "fa", "json") -> "https://x.com/setting/fa.json"
|
|
143
|
+
* (undefined | "", undefined, "fa") -> "/fa"
|
|
144
|
+
* The protocol part of `base` ("https://") is left alone.
|
|
145
|
+
*/
|
|
146
|
+
declare function buildI18nUrl(base: string | null | undefined, scope: string | null | undefined, lang: string, ext?: string | null | undefined): string;
|
|
117
147
|
|
|
118
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* Default loader: GET `{baseUrl}/{lang}{ext}` and `{baseUrl}/{scope}/{lang}{ext}`.
|
|
150
|
+
* Goes through your HttpClient interceptors.
|
|
151
|
+
* Config is read on every request, so values supplied later via `I18nService.init()` /
|
|
152
|
+
* `configure()` (for example `baseUrl`) are picked up.
|
|
153
|
+
*/
|
|
119
154
|
declare class HttpI18nLoader implements I18nLoader {
|
|
120
155
|
private readonly http;
|
|
121
156
|
private readonly cfg;
|
|
@@ -130,14 +165,19 @@ declare class I18nService {
|
|
|
130
165
|
private readonly doc;
|
|
131
166
|
private readonly _lang;
|
|
132
167
|
private readonly _rev;
|
|
168
|
+
private readonly _langs;
|
|
169
|
+
private readonly _ready;
|
|
133
170
|
/** Active language (reactive). */
|
|
134
171
|
readonly lang: Signal<string>;
|
|
135
172
|
/** Bumps whenever the active language or any dictionary changes. */
|
|
136
173
|
readonly revision: Signal<number>;
|
|
137
174
|
readonly dir: Signal<"rtl" | "ltr">;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
175
|
+
/** Supported languages (a signal: they may be supplied after startup via `init()` / `configure()`). */
|
|
176
|
+
readonly langs: Signal<readonly string[]>;
|
|
177
|
+
/** `true` once the first language has been activated. Handy for a splash screen. */
|
|
178
|
+
readonly ready: Signal<boolean>;
|
|
179
|
+
private get fallbacks();
|
|
180
|
+
private get warn();
|
|
141
181
|
private readonly dicts;
|
|
142
182
|
private readonly loaded;
|
|
143
183
|
private readonly inflight;
|
|
@@ -163,6 +203,24 @@ declare class I18nService {
|
|
|
163
203
|
* Nothing renders half-translated and no "missing" flash occurs.
|
|
164
204
|
*/
|
|
165
205
|
use(lang: string): Promise<void>;
|
|
206
|
+
/**
|
|
207
|
+
* Complete the configuration and activate the first language in one call. Use it from your own
|
|
208
|
+
* APP_INITIALIZER when the language list is only known at runtime (e.g. from the backend):
|
|
209
|
+
*
|
|
210
|
+
* ```ts
|
|
211
|
+
* await i18n.init({ langs: ['fa', 'en'], defaultLang: 'fa', baseUrl: apiUrl, lang: user.lang });
|
|
212
|
+
* ```
|
|
213
|
+
* `lang` is used when it is in `langs`; otherwise stored > browser (opt-in) > `defaultLang`.
|
|
214
|
+
* Rejects when the files cannot be loaded, so the initializer can show an error page.
|
|
215
|
+
*/
|
|
216
|
+
init(options?: I18nInitOptions): Promise<void>;
|
|
217
|
+
/**
|
|
218
|
+
* Update options after startup (languages, baseUrl, fallbacks, ...). Already downloaded files stay cached.
|
|
219
|
+
* `loader` and `autoInit` can only be set in `provideI18n()`.
|
|
220
|
+
*/
|
|
221
|
+
configure(patch: I18nRuntimeConfig): void;
|
|
222
|
+
private syncLangs;
|
|
223
|
+
private activate;
|
|
166
224
|
/** Download a language without activating it. */
|
|
167
225
|
preload(lang: string): Promise<void>;
|
|
168
226
|
/** Language to start with: stored > browser (opt-in) > default. */
|
|
@@ -185,13 +243,23 @@ declare class I18nService {
|
|
|
185
243
|
}
|
|
186
244
|
|
|
187
245
|
/**
|
|
246
|
+
* Static configuration (everything known at build time):
|
|
188
247
|
* ```ts
|
|
189
248
|
* provideHttpClient(),
|
|
190
249
|
* provideI18n({ langs: ['fa', 'en'], defaultLang: 'fa', fallbackLangs: ['en'] })
|
|
191
250
|
* ```
|
|
192
|
-
* The global dictionary of the initial language is loaded before the app starts.
|
|
251
|
+
* The global dictionary of the initial language is then loaded before the app starts.
|
|
252
|
+
*
|
|
253
|
+
* Deferred configuration (languages come from your backend): omit `langs`/`defaultLang`
|
|
254
|
+
* and call `await inject(I18nService).init({ langs, defaultLang, baseUrl, lang })`
|
|
255
|
+
* from your own APP_INITIALIZER once you know them:
|
|
256
|
+
* ```ts
|
|
257
|
+
* provideI18n({ fallbackLangs: ['fa'] }), // no automatic initializer
|
|
258
|
+
* provideAppInitializer(() => AppInitializer()), // calls i18n.init(...)
|
|
259
|
+
* ```
|
|
260
|
+
* Pass `autoInit: false` to force this mode even when `langs` is given.
|
|
193
261
|
*/
|
|
194
|
-
declare function provideI18n(config
|
|
262
|
+
declare function provideI18n(config?: I18nConfig): EnvironmentProviders;
|
|
195
263
|
|
|
196
264
|
/**
|
|
197
265
|
* Put in `route.providers`. Runs when the route injector is created (before guards),
|
|
@@ -209,5 +277,5 @@ declare function injectT(): TranslateFn;
|
|
|
209
277
|
/** `imports: [TR]` brings the pipe and both directives into a standalone component. */
|
|
210
278
|
declare const TR: readonly [typeof TrPipe, typeof TrDirective, typeof TrKeyDirective];
|
|
211
279
|
|
|
212
|
-
export { HttpI18nLoader, I18N_CONFIG,
|
|
213
|
-
export type { Dictionary, I18nLoader, MissingHandler, Params, TrContext, TranslateFn, Transpiler };
|
|
280
|
+
export { HttpI18nLoader, I18N_CONFIG, I18N_DEFAULTS, I18N_LOADER, I18nService, TR, TrDirective, TrKeyDirective, TrPipe, buildI18nUrl, flatten, i18nReadyGuard, injectT, interpolate, marker, provideI18n, provideI18nScope, translateSignal };
|
|
281
|
+
export type { Dictionary, I18nConfig, I18nInitOptions, I18nLoader, I18nRuntimeConfig, MissingHandler, Params, TrContext, TranslateFn, Transpiler };
|