@ng-linguo/linguo 0.9.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 +25 -0
- package/fesm2022/ng-linguo-linguo-http.mjs +32 -0
- package/fesm2022/ng-linguo-linguo-http.mjs.map +1 -0
- package/fesm2022/ng-linguo-linguo-icu.mjs +104 -0
- package/fesm2022/ng-linguo-linguo-icu.mjs.map +1 -0
- package/fesm2022/ng-linguo-linguo.mjs +775 -0
- package/fesm2022/ng-linguo-linguo.mjs.map +1 -0
- package/package.json +59 -0
- package/types/ng-linguo-linguo-http.d.ts +30 -0
- package/types/ng-linguo-linguo-icu.d.ts +86 -0
- package/types/ng-linguo-linguo.d.ts +454 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import * as _ngrx_signals from '@ngrx/signals';
|
|
2
|
+
import * as _angular_core from '@angular/core';
|
|
3
|
+
import { EnvironmentProviders, PipeTransform, OnInit, TemplateRef, InjectionToken } from '@angular/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A flat map of translation keys to their resolved string values for a single
|
|
7
|
+
* language. Values are plain strings (optionally containing `[name]...[/name]`
|
|
8
|
+
* slot tags and ICU syntax) — never HTML. This is the on-disk JSON shape, kept
|
|
9
|
+
* stable since v1 so translators can keep using existing tooling.
|
|
10
|
+
*/
|
|
11
|
+
type Translations = Readonly<Record<string, string>>;
|
|
12
|
+
/**
|
|
13
|
+
* Strategy for fetching the {@link Translations} for a given language.
|
|
14
|
+
*
|
|
15
|
+
* Implementations live in their own packages (for example
|
|
16
|
+
* `@ng-linguo/linguo/http`); `@ng-linguo/linguo` only depends on this interface
|
|
17
|
+
* so it never reaches for `fetch`/XHR itself.
|
|
18
|
+
*/
|
|
19
|
+
interface TranslationLoader {
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the translations for `lang`. Rejecting the promise signals a load
|
|
22
|
+
* failure to the store; resolving with an empty map is a valid "no
|
|
23
|
+
* translations" result.
|
|
24
|
+
*
|
|
25
|
+
* @param lang BCP-47 language tag, for example `'en'` or `'pl'`.
|
|
26
|
+
*/
|
|
27
|
+
load(lang: string): Promise<Translations>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Bootstrap configuration for the translation runtime, passed to
|
|
31
|
+
* `provideTranslate`. Loading is never started implicitly from this config —
|
|
32
|
+
* the consumer triggers the first load explicitly.
|
|
33
|
+
*/
|
|
34
|
+
interface TranslateConfig {
|
|
35
|
+
/** Language the store reports as current before anything is loaded. */
|
|
36
|
+
readonly defaultLang: string;
|
|
37
|
+
/**
|
|
38
|
+
* How translations are fetched. Either a ready-made {@link TranslationLoader}
|
|
39
|
+
* (e.g. a static dictionary or a `fetch`-based loader), or a **factory** that
|
|
40
|
+
* returns one. The factory runs inside Angular's injection context, so use it
|
|
41
|
+
* for loaders that inject Angular services — such as `createHttpLoader()` from
|
|
42
|
+
* `@ng-linguo/linguo/http`, which needs `HttpClient`:
|
|
43
|
+
*
|
|
44
|
+
* ```ts
|
|
45
|
+
* provideTranslate({ defaultLang: 'en', loader: () => createHttpLoader() });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
readonly loader: TranslationLoader | (() => TranslationLoader);
|
|
49
|
+
/**
|
|
50
|
+
* Languages the app ships. Used by {@link TranslateStore.restoreLang} to match
|
|
51
|
+
* a persisted or browser-preferred value to one that actually exists. Browser
|
|
52
|
+
* matching is skipped when this is omitted (so an unshipped language is never
|
|
53
|
+
* auto-selected).
|
|
54
|
+
*/
|
|
55
|
+
readonly supportedLangs?: readonly string[];
|
|
56
|
+
/**
|
|
57
|
+
* Write the active language to `localStorage` whenever it changes (the
|
|
58
|
+
* **persist** side). Defaults to `true`. SSR-safe (a no-op when not running
|
|
59
|
+
* in a browser). To stop reading the saved value on startup as well, see
|
|
60
|
+
* {@link restoreSelectedLanguage}.
|
|
61
|
+
*/
|
|
62
|
+
readonly persistSelectedLanguage?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Read the persisted language back on startup, inside
|
|
65
|
+
* {@link TranslateStore.restoreLang} (the **restore** side). Decoupled from
|
|
66
|
+
* {@link persistSelectedLanguage} so an app can keep persisting while owning
|
|
67
|
+
* the restore decision itself — set this to `false` and run your own
|
|
68
|
+
* selection logic, or just call `setLang(...)` instead of `restoreLang()`.
|
|
69
|
+
*
|
|
70
|
+
* Defaults to `persistSelectedLanguage` (so disabling persistence alone still
|
|
71
|
+
* disables restore, as before); set it explicitly to override. SSR-safe.
|
|
72
|
+
*/
|
|
73
|
+
readonly restoreSelectedLanguage?: boolean;
|
|
74
|
+
/** `localStorage` key for the persisted language. Defaults to `ng-linguo.lang`. */
|
|
75
|
+
readonly persistKey?: string;
|
|
76
|
+
/**
|
|
77
|
+
* On first run (nothing persisted), use the browser's preferred language
|
|
78
|
+
* (`navigator.languages`) matched against {@link supportedLangs}. Defaults to
|
|
79
|
+
* `true`. SSR-safe.
|
|
80
|
+
*/
|
|
81
|
+
readonly detectBrowserLanguage?: boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Options for the `t` pipe, passed as a single object:
|
|
85
|
+
* `{{ 'Hello {$name}!' | t: { params: { name } } }}`.
|
|
86
|
+
*/
|
|
87
|
+
interface TranslateOptions {
|
|
88
|
+
/** ICU arguments, formatted via `@ng-linguo/linguo/icu` when provided. */
|
|
89
|
+
readonly params?: Record<string, unknown>;
|
|
90
|
+
/**
|
|
91
|
+
* Disambiguating/contextual text for keys that share the same source text.
|
|
92
|
+
* It is part of the key (gettext `msgctxt`), so distinct contexts get
|
|
93
|
+
* distinct translations; it may be descriptive ("Button that starts a game").
|
|
94
|
+
*/
|
|
95
|
+
readonly context?: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The reactive translation runtime, implemented as an `@ngrx/signals`
|
|
100
|
+
* `signalStore`. Consumers inject it and read state through signals; there are
|
|
101
|
+
* no `Observable` getters on the public surface.
|
|
102
|
+
*
|
|
103
|
+
* State is not loaded implicitly. Call {@link TranslateStore.restoreLang} once
|
|
104
|
+
* at startup to pick the language (persisted → browser → default) and load it,
|
|
105
|
+
* or {@link TranslateStore.setLang} to switch to a specific one.
|
|
106
|
+
* {@link TranslateStore.isReady} stays `false` until a language has loaded, so
|
|
107
|
+
* UI can gate on it to avoid a flash of untranslated content.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* const store = inject(TranslateStore);
|
|
112
|
+
* store.currentLang(); // Signal<string>
|
|
113
|
+
* store.isReady(); // Signal<boolean>
|
|
114
|
+
* await store.restoreLang(); // startup: persisted ?? browser ?? default
|
|
115
|
+
* await store.setLang('pl'); // explicit switch
|
|
116
|
+
* store.translate('greeting');
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
declare const TranslateStore: _angular_core.Type<{
|
|
120
|
+
readonly currentLang: _angular_core.Signal<string>;
|
|
121
|
+
readonly isReady: _angular_core.Signal<boolean>;
|
|
122
|
+
readonly translations: _angular_core.Signal<Readonly<Record<string, string>>>;
|
|
123
|
+
setLang: (lang: string) => Promise<void>;
|
|
124
|
+
restoreLang: () => Promise<void>;
|
|
125
|
+
translate: (key: string, context?: string) => string;
|
|
126
|
+
} & _ngrx_signals.StateSource<{
|
|
127
|
+
readonly currentLang: string;
|
|
128
|
+
readonly isReady: boolean;
|
|
129
|
+
readonly translations: Translations;
|
|
130
|
+
}>>;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Register the translation runtime for an application or a feature scope.
|
|
134
|
+
*
|
|
135
|
+
* Add the returned providers to `bootstrapApplication`'s `providers` (or a
|
|
136
|
+
* route's `providers`). This only wires up configuration — it never starts a
|
|
137
|
+
* load, so no HTTP is fired during DI initialization. Trigger the first load
|
|
138
|
+
* explicitly via `TranslateStore.setLang`.
|
|
139
|
+
*
|
|
140
|
+
* The `loader` may be a ready-made loader object, or a factory `() => loader`
|
|
141
|
+
* that is run inside the injection context — use the factory form for loaders
|
|
142
|
+
* that inject Angular services (e.g. `createHttpLoader()`, which needs
|
|
143
|
+
* `HttpClient`).
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* // a static dictionary or fetch-based loader
|
|
148
|
+
* provideTranslate({ defaultLang: 'en', loader: myLoader });
|
|
149
|
+
*
|
|
150
|
+
* // an HttpClient-backed loader (factory form)
|
|
151
|
+
* provideTranslate({ defaultLang: 'en', loader: () => createHttpLoader() });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
declare function provideTranslate(config: TranslateConfig): EnvironmentProviders;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Resolve a translation key to its string for the current language, with options
|
|
158
|
+
* passed as a single object: ICU `params` and a disambiguating `context`.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```html
|
|
162
|
+
* {{ 'Play' | t }}
|
|
163
|
+
* {{ 'Play' | t: { context: 'game' } }}
|
|
164
|
+
* {{ 'Hello {$name}!' | t: { params: { name } } }}
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* The key is the source text; a missing key renders as itself. ICU `params` are
|
|
168
|
+
* applied by the formatter from `@ng-linguo/linguo/icu` (`provideIcu`); without
|
|
169
|
+
* it the message is returned unformatted.
|
|
170
|
+
*
|
|
171
|
+
* Impure so it re-evaluates against the store's signals each change detection,
|
|
172
|
+
* re-rendering when the language changes. To keep that cheap it **memoizes** by
|
|
173
|
+
* value: the lookup/format only re-runs when the key, `context`, `params`
|
|
174
|
+
* contents, or the active language actually change — so a fresh `{ params: … }`
|
|
175
|
+
* literal on every change-detection pass costs only an equality check. For hot
|
|
176
|
+
* or looped bindings, prefer `injectTranslate()` inside a `computed()`, which
|
|
177
|
+
* does zero work per change-detection pass.
|
|
178
|
+
*/
|
|
179
|
+
declare class TranslatePipe implements PipeTransform {
|
|
180
|
+
private readonly t;
|
|
181
|
+
private readonly translations;
|
|
182
|
+
private cache;
|
|
183
|
+
transform(key: string, options?: TranslateOptions): string;
|
|
184
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TranslatePipe, never>;
|
|
185
|
+
static ɵpipe: _angular_core.ɵɵPipeDeclaration<TranslatePipe, "t", true>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Resolves a key to its translation for the current language, with optional ICU
|
|
190
|
+
* `params` and `context` — the function form of the `t` pipe.
|
|
191
|
+
*/
|
|
192
|
+
type TranslateFn = (key: string, options?: TranslateOptions) => string;
|
|
193
|
+
/**
|
|
194
|
+
* Obtain a {@link TranslateFn} for use in component code — the TypeScript
|
|
195
|
+
* counterpart of the `t` pipe.
|
|
196
|
+
*
|
|
197
|
+
* Call it in an injection context (a field initializer or constructor); the
|
|
198
|
+
* returned `t` reads the store's signals each time it runs, so it stays reactive
|
|
199
|
+
* when used in a template binding or inside a `computed`.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* export class Greeting {
|
|
204
|
+
* private readonly t = injectTranslate();
|
|
205
|
+
* protected readonly name = signal('Ada');
|
|
206
|
+
* protected readonly text = computed(() =>
|
|
207
|
+
* this.t('Hello {$name}!', { params: { name: this.name() } }),
|
|
208
|
+
* );
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
declare function injectTranslate(): TranslateFn;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Options for {@link mark}. Only `context` is read (by `@ng-linguo/extract`);
|
|
216
|
+
* `params` is accepted so a single options object can be shared with the `t`
|
|
217
|
+
* pipe / directive call that ultimately renders the message.
|
|
218
|
+
*/
|
|
219
|
+
interface MarkOptions {
|
|
220
|
+
/**
|
|
221
|
+
* Disambiguating/contextual text recorded as the catalog `msgctxt`. It is part
|
|
222
|
+
* of the key, so it must match the `context` passed at the consuming
|
|
223
|
+
* pipe/directive for the runtime lookup to resolve. It doubles as a note for
|
|
224
|
+
* translators (e.g. `'file = a document on disk'`).
|
|
225
|
+
*/
|
|
226
|
+
readonly context?: string;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Mark a string as a translatable message so `@ng-linguo/extract` collects it,
|
|
230
|
+
* returning the string unchanged (it does not translate at runtime).
|
|
231
|
+
*
|
|
232
|
+
* Use it for messages that are not written inline at a `t` pipe or `[t]`
|
|
233
|
+
* directive — for example an ICU message kept in a component field (an MF2
|
|
234
|
+
* pattern contains `{{ … }}`, which collides with Angular's `{{ }}` binding).
|
|
235
|
+
* The marked string is still translated at render time by the pipe/directive
|
|
236
|
+
* that consumes it.
|
|
237
|
+
*
|
|
238
|
+
* Pass `context` to record a `msgctxt`/translator note for the entry. Because
|
|
239
|
+
* context is part of the key, the **same** `context` must be supplied where the
|
|
240
|
+
* marked string is rendered (`| t: { context }` or `tContext`), or the runtime
|
|
241
|
+
* lookup will not find the contextual entry.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* readonly fileCount = mark(
|
|
246
|
+
* '.input {$count :number} .match $count one {{{$count} file}} * {{{$count} files}}',
|
|
247
|
+
* { context: 'file = a document on disk' },
|
|
248
|
+
* );
|
|
249
|
+
* // template: {{ fileCount | t: { params: { count: count() }, context: 'file = a document on disk' } }}
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
declare function mark(message: string, options?: MarkOptions): string;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* A node in a parsed slot tree produced by {@link parseSlots}.
|
|
256
|
+
*
|
|
257
|
+
* - `text` nodes carry literal, translator-authored text. They are rendered as
|
|
258
|
+
* DOM text nodes — never as HTML — which is how the library keeps its XSS
|
|
259
|
+
* surface at zero by construction.
|
|
260
|
+
* - `slot` nodes correspond to a `[name]...[/name]` region that the developer
|
|
261
|
+
* fills with an `<ng-template>`. The bracket syntax resembles BBCode, but the
|
|
262
|
+
* names are arbitrary and author-chosen and carry no predefined rendering —
|
|
263
|
+
* each is a named slot bound to a template. Slots may nest.
|
|
264
|
+
*/
|
|
265
|
+
type SlotNode = {
|
|
266
|
+
readonly kind: 'text';
|
|
267
|
+
readonly value: string;
|
|
268
|
+
} | {
|
|
269
|
+
readonly kind: 'slot';
|
|
270
|
+
readonly name: string;
|
|
271
|
+
readonly children: readonly SlotNode[];
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Parse a translator-authored string into a tree of {@link SlotNode}s.
|
|
275
|
+
*
|
|
276
|
+
* The parser is total: every input produces a tree, and any malformed
|
|
277
|
+
* construct (a stray `[`, an unclosed tag, a mismatched closing tag) degrades
|
|
278
|
+
* gracefully to literal text rather than throwing. Well-formed
|
|
279
|
+
* `[name]...[/name]` regions — including nested ones — become `slot` nodes. To
|
|
280
|
+
* include a literal `[` (so text such as `[note]` is not read as a tag), double
|
|
281
|
+
* it: `[[` parses to a single `[`.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```ts
|
|
285
|
+
* parseSlots('Hello [b]world[/b]!');
|
|
286
|
+
* // [
|
|
287
|
+
* // { kind: 'text', value: 'Hello ' },
|
|
288
|
+
* // { kind: 'slot', name: 'b', children: [{ kind: 'text', value: 'world' }] },
|
|
289
|
+
* // { kind: 'text', value: '!' },
|
|
290
|
+
* // ]
|
|
291
|
+
*
|
|
292
|
+
* parseSlots('See [[b] for bold');
|
|
293
|
+
* // [{ kind: 'text', value: 'See [b] for bold' }]
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
declare function parseSlots(input: string): readonly SlotNode[];
|
|
297
|
+
/**
|
|
298
|
+
* Flatten a slot string to plain text: slot tags are dropped and their inner
|
|
299
|
+
* text is kept. This is how the `t` pipe and {@link injectTranslate} render a
|
|
300
|
+
* message containing `[name]...[/name]` slots — they return a string, so the
|
|
301
|
+
* markup degrades to text (the `[t]` directive renders the slots into templates
|
|
302
|
+
* instead).
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```ts
|
|
306
|
+
* slotsToText('Read the [docs]documentation[/docs] now'); // 'Read the documentation now'
|
|
307
|
+
* slotsToText('Press [[Enter] to send'); // 'Press [Enter] to send'
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
declare function slotsToText(input: string): string;
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Context handed to a slot's `<ng-template tFor>`:
|
|
314
|
+
*
|
|
315
|
+
* - `$implicit` — the slot's inner text, flattened to a string. `let-text` binds
|
|
316
|
+
* it, so `{{ text }}` renders a plain-text slot (the common case).
|
|
317
|
+
* - `children` — the slot's parsed child nodes, for binding *nested* slots to
|
|
318
|
+
* their own templates with `*tRender` instead of flattening them to text. Bind
|
|
319
|
+
* it with `let-kids="children"`. See `TranslateSlotOutlet`.
|
|
320
|
+
*/
|
|
321
|
+
interface TranslateSlotContext {
|
|
322
|
+
readonly $implicit: string;
|
|
323
|
+
readonly children: readonly SlotNode[];
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Provides an `<ng-template>` as the renderer for a named slot of the enclosing
|
|
328
|
+
* `[t]` element. The `[name]...[/name]` bracket syntax resembles BBCode, but the
|
|
329
|
+
* name is arbitrary and author-chosen — it identifies a slot to fill, not a tag
|
|
330
|
+
* with predefined HTML. Declared as a child of the `[t]` element (it renders as
|
|
331
|
+
* an invisible anchor), so the name is scoped to that element. The template
|
|
332
|
+
* receives the slot's inner text (`let-text`) and parsed children
|
|
333
|
+
* (`let-kids="children"`, for nesting via `*tRender`) as its context.
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```html
|
|
337
|
+
* <ng-template tFor="docs" let-text>
|
|
338
|
+
* <a routerLink="/docs">{{ text }}</a>
|
|
339
|
+
* </ng-template>
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
342
|
+
declare class TranslateSlot {
|
|
343
|
+
/** Slot name, matching `[name]...[/name]` in the translation. */
|
|
344
|
+
readonly name: _angular_core.InputSignal<string>;
|
|
345
|
+
readonly templateRef: TemplateRef<TranslateSlotContext>;
|
|
346
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TranslateSlot, never>;
|
|
347
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TranslateSlot, "ng-template[tFor]", never, { "name": { "alias": "tFor"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Translate the `t` message and render it into the element, applying ICU `tParams`
|
|
351
|
+
* and binding any `[name]...[/name]` slot regions to `<ng-template tFor>`
|
|
352
|
+
* children.
|
|
353
|
+
*
|
|
354
|
+
* The message is the `t` attribute (a string expression), so it may contain both
|
|
355
|
+
* ICU (`{$name}`) and slot tags (`[name]`) safely. Rendered text is emitted as DOM
|
|
356
|
+
* text nodes, never HTML (CLAUDE.md §5.1); a slot with no matching template
|
|
357
|
+
* degrades to its inner text. Nested slots bind to their own templates when the
|
|
358
|
+
* parent template marks where they go with `*tRender` (see
|
|
359
|
+
* `TranslateSlotOutlet`); otherwise a nested slot renders as text. Re-renders
|
|
360
|
+
* when the language, params, or a slot template changes.
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```html
|
|
364
|
+
* <p t="Hello {$name}!" [tParams]="{ name }"></p>
|
|
365
|
+
*
|
|
366
|
+
* <p t="Read the [docs]documentation[/docs] to get started">
|
|
367
|
+
* <ng-template tFor="docs" let-text>
|
|
368
|
+
* <a routerLink="/docs">{{ text }}</a>
|
|
369
|
+
* </ng-template>
|
|
370
|
+
* </p>
|
|
371
|
+
* ```
|
|
372
|
+
*/
|
|
373
|
+
declare class TranslateDirective implements OnInit {
|
|
374
|
+
private readonly store;
|
|
375
|
+
private readonly host;
|
|
376
|
+
private readonly renderer;
|
|
377
|
+
private readonly formatter;
|
|
378
|
+
private readonly slotRenderer;
|
|
379
|
+
/** Source message (the translation key); may contain ICU and slot tags. */
|
|
380
|
+
readonly message: _angular_core.InputSignal<string>;
|
|
381
|
+
/** ICU arguments, formatted via `@ng-linguo/linguo/icu` when provided. */
|
|
382
|
+
readonly tParams: _angular_core.InputSignal<Record<string, unknown> | undefined>;
|
|
383
|
+
/** Optional disambiguating/contextual text (part of the key). */
|
|
384
|
+
readonly tContext: _angular_core.InputSignal<string>;
|
|
385
|
+
private readonly slots;
|
|
386
|
+
private templates;
|
|
387
|
+
constructor();
|
|
388
|
+
ngOnInit(): void;
|
|
389
|
+
/**
|
|
390
|
+
* Render a nested slot's `nodes` into `parent` before `before`, reusing the
|
|
391
|
+
* current templates and the shared renderer. Internal: called by
|
|
392
|
+
* `TranslateSlotOutlet` (`*tRender`); not part of the consumer-facing API.
|
|
393
|
+
*/
|
|
394
|
+
renderChildren(parent: Node, before: Node, nodes: readonly SlotNode[]): void;
|
|
395
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TranslateDirective, never>;
|
|
396
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TranslateDirective, "[t]", never, { "message": { "alias": "t"; "required": true; "isSignal": true; }; "tParams": { "alias": "tParams"; "required": false; "isSignal": true; }; "tContext": { "alias": "tContext"; "required": false; "isSignal": true; }; }, {}, ["slots"], never, true, never>;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Renders the *children* of a slot at this position, so a nested slot binds to
|
|
401
|
+
* its own `<ng-template>` instead of flattening to text. Without it, a slot
|
|
402
|
+
* inside a templated slot renders as plain text (its `$implicit` value); with
|
|
403
|
+
* it, each nested slot finds its own `tFor` template.
|
|
404
|
+
*
|
|
405
|
+
* Bind the `children` from the enclosing slot's context and place the outlet
|
|
406
|
+
* where the nested content should appear:
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* ```html
|
|
410
|
+
* <p t="Agree to our [link]Terms and [b]Conditions[/b][/link]">
|
|
411
|
+
* <ng-template tFor="link" let-kids="children">
|
|
412
|
+
* <a href="/terms"><ng-container *tRender="kids" /></a>
|
|
413
|
+
* </ng-template>
|
|
414
|
+
* <ng-template tFor="b" let-text><strong>{{ text }}</strong></ng-template>
|
|
415
|
+
* </p>
|
|
416
|
+
* ```
|
|
417
|
+
*
|
|
418
|
+
* Valid only inside a `[t]` element's slot template — it resolves the enclosing
|
|
419
|
+
* {@link TranslateDirective} and renders through its shared engine, so nested
|
|
420
|
+
* views are torn down with the rest on a language or params change.
|
|
421
|
+
*/
|
|
422
|
+
declare class TranslateSlotOutlet implements OnInit {
|
|
423
|
+
/** The nodes to render — the `children` value from the slot context. */
|
|
424
|
+
readonly nodes: _angular_core.InputSignal<readonly SlotNode[]>;
|
|
425
|
+
private readonly host;
|
|
426
|
+
private readonly anchor;
|
|
427
|
+
ngOnInit(): void;
|
|
428
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TranslateSlotOutlet, never>;
|
|
429
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TranslateSlotOutlet, "[tRender]", never, { "nodes": { "alias": "tRender"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Formats a resolved message against runtime arguments — the seam that lets the
|
|
434
|
+
* `translate` pipe render ICU messages without `core` depending on any ICU
|
|
435
|
+
* library. `@ng-linguo/linguo/icu`'s `provideIcu` supplies an implementation; when none
|
|
436
|
+
* is provided the pipe simply returns the message unformatted.
|
|
437
|
+
*/
|
|
438
|
+
interface MessageFormatter {
|
|
439
|
+
/**
|
|
440
|
+
* @param message The resolved (translated) message, possibly containing ICU
|
|
441
|
+
* placeholders.
|
|
442
|
+
* @param args Named arguments to substitute (counts, names, dates…).
|
|
443
|
+
* @param locale BCP-47 locale for plural rules and number/date formatting.
|
|
444
|
+
*/
|
|
445
|
+
format(message: string, args: Record<string, unknown>, locale: string): string;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* DI token for an optional {@link MessageFormatter}. Provided by
|
|
449
|
+
* `@ng-linguo/linguo/icu`'s `provideIcu`; absent by default.
|
|
450
|
+
*/
|
|
451
|
+
declare const MESSAGE_FORMATTER: InjectionToken<MessageFormatter>;
|
|
452
|
+
|
|
453
|
+
export { MESSAGE_FORMATTER, TranslateDirective, TranslatePipe, TranslateSlot, TranslateSlotOutlet, TranslateStore, injectTranslate, mark, parseSlots, provideTranslate, slotsToText };
|
|
454
|
+
export type { MarkOptions, MessageFormatter, SlotNode, TranslateConfig, TranslateFn, TranslateOptions, TranslateSlotContext, TranslationLoader, Translations };
|