@mk-kit/ui 0.54.0 → 0.55.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.
@@ -0,0 +1,251 @@
1
+ import * as rxjs from 'rxjs';
2
+ import * as i0 from '@angular/core';
3
+ import { InjectionToken, PipeTransform, EnvironmentProviders } from '@angular/core';
4
+
5
+ /**
6
+ * A translation file: nested objects of strings. Keys are addressed with
7
+ * dots (`checkout.cart.total`), so `{ checkout: { cart: { total: '…' } } }`
8
+ * and `{ 'checkout.cart.total': '…' }` are the same dictionary. This is the
9
+ * plain JSON most apps already ship (ngx-translate's format included).
10
+ */
11
+ interface MkTranslationTree {
12
+ [key: string]: string | MkTranslationTree;
13
+ }
14
+ /** Flattened dictionary: dotted key → string. */
15
+ type MkFlatTranslations = Record<string, string>;
16
+ /** Values interpolated into `{{name}}` placeholders. */
17
+ type MkTranslateParams = Record<string, unknown>;
18
+ /**
19
+ * Where a language's strings come from. Return the tree (or a promise of
20
+ * it); the service flattens, caches per language and merges overrides.
21
+ */
22
+ interface MkTranslateLoader {
23
+ load(lang: string): Promise<MkTranslationTree> | MkTranslationTree;
24
+ }
25
+ /** A loader factory; runs inside an injection context, so `inject()` works. */
26
+ type MkTranslateLoaderFactory = () => MkTranslateLoader;
27
+ /** Options for {@link provideMkTranslate}. */
28
+ interface MkTranslateConfig {
29
+ /** Language loaded first and used until `use()` switches it. */
30
+ lang: string;
31
+ /** Looked up when the active language lacks a key. Default: none. */
32
+ fallbackLang?: string;
33
+ /** Base strings — the bundled JSON, typically ({@link mkHttpTranslateLoader}). */
34
+ loader: MkTranslateLoaderFactory;
35
+ /**
36
+ * Optional second source merged OVER the base per language: edits kept in
37
+ * a database, a tenant's wording, a translator's work in progress. A
38
+ * loader that throws or resolves `{}` leaves the base untouched.
39
+ */
40
+ overrides?: MkTranslateLoaderFactory;
41
+ /**
42
+ * Block application bootstrap until the initial language is loaded, so the
43
+ * first render never shows raw keys and `instant()` calls inside
44
+ * `computed()` never cache them. Default `true`.
45
+ */
46
+ preload?: boolean;
47
+ /**
48
+ * Mirror the active language onto `<html lang>` (server and browser), so
49
+ * screen readers, hyphenation and search engines follow `use()`. Default
50
+ * `true`.
51
+ */
52
+ documentLang?: boolean;
53
+ /**
54
+ * Called for a key missing in both the active and the fallback language.
55
+ * Return a string to render instead of the key. Missing keys are also
56
+ * collected in {@link MkTranslate.missingKeys}.
57
+ */
58
+ onMissing?: (key: string, lang: string) => string | undefined | void;
59
+ }
60
+
61
+ /** Configuration token; set by {@link provideMkTranslate}. */
62
+ declare const MK_TRANSLATE_CONFIG: InjectionToken<MkTranslateConfig>;
63
+ /** `{ a: { b: 'x' } }` → `{ 'a.b': 'x' }`; already-dotted keys pass through. */
64
+ declare function mkFlattenTranslations(tree: MkTranslationTree | null | undefined, prefix?: string, out?: MkFlatTranslations): MkFlatTranslations;
65
+ /** `{ 'a.b': 'x' }` → `{ a: { b: 'x' } }` — for editors that write files back. */
66
+ declare function mkUnflattenTranslations(flat: MkFlatTranslations): MkTranslationTree;
67
+ /** Replace `{{name}}` placeholders; unknown names are left in place. */
68
+ declare function mkInterpolate(template: string, params?: MkTranslateParams): string;
69
+ /**
70
+ * App translations as signals: a `lang` you switch with `use()`, `instant()`
71
+ * for code, the `translate` pipe for templates, and `plural()` for CLDR
72
+ * count forms. Dictionaries are the plain nested JSON you already have; an
73
+ * optional overrides loader (a database of edits, say) is merged on top per
74
+ * language. On the server the loaded strings ride to the browser through
75
+ * `TransferState`, so hydration never refetches or flashes raw keys.
76
+ *
77
+ * ```ts
78
+ * provideMkTranslate({
79
+ * lang: 'pl',
80
+ * fallbackLang: 'pl',
81
+ * loader: mkHttpTranslateLoader({ prefix: '/assets/i18n/' }),
82
+ * });
83
+ * ```
84
+ * ```html
85
+ * {{ 'checkout.cart.total' | translate }}
86
+ * {{ 'checkout.cart.freeDeliveryMissing' | translate: { amount: 12 } }}
87
+ * ```
88
+ */
89
+ declare class MkTranslate {
90
+ private readonly config;
91
+ private readonly injector;
92
+ private readonly transfer;
93
+ private readonly isServer;
94
+ private readonly document;
95
+ private loader;
96
+ private overridesLoader;
97
+ private readonly dictionaries;
98
+ private readonly declared;
99
+ private readonly pending;
100
+ /** Bumped whenever a dictionary changes, so readers recompute. */
101
+ private readonly version;
102
+ private readonly missing;
103
+ /** The active language. Read it in a `computed()` to follow switches. */
104
+ readonly lang: i0.WritableSignal<string>;
105
+ /** `true` once the active language's strings are in memory. */
106
+ readonly ready: i0.Signal<boolean>;
107
+ /** `lang` as an observable, for code still written around streams. */
108
+ readonly langChange: rxjs.Observable<string>;
109
+ /** Keys asked for that neither the active nor the fallback language has. */
110
+ readonly missingKeys: i0.Signal<string[]>;
111
+ constructor();
112
+ /** The active language as a plain string (for non-reactive call sites). */
113
+ getCurrentLang(): string;
114
+ /** ngx-translate-compatible alias of {@link getCurrentLang}. */
115
+ get currentLang(): string;
116
+ /** Languages known to the service: loaded ones plus any added with {@link addLangs}. */
117
+ getLangs(): string[];
118
+ /** Declare languages up front (a switcher's list); loading still happens on `use()`. */
119
+ addLangs(langs: string[]): void;
120
+ /**
121
+ * ngx-translate-compatible alias: `setTranslation(lang, strings, true)`
122
+ * merges like {@link patch}, `false` (the default there) replaces like
123
+ * {@link set}.
124
+ */
125
+ setTranslation(lang: string, strings: MkTranslationTree | MkFlatTranslations, shouldMerge?: boolean): void;
126
+ /**
127
+ * Load `lang` (once — later calls are cached) and make it active. Resolves
128
+ * when the strings are in memory; a failed load rejects and leaves the
129
+ * previous language active.
130
+ */
131
+ use(lang: string): Promise<void>;
132
+ /** Load a language into memory without switching to it. */
133
+ load(lang: string): Promise<void>;
134
+ /**
135
+ * Translate `key` in the active language, then the fallback; `{{name}}`
136
+ * placeholders come from `params`. A missing key renders as the key
137
+ * itself (or whatever `onMissing` returns) and is recorded in
138
+ * {@link missingKeys}. Reactive: reading it inside a template or a
139
+ * `computed()` re-runs on language switch and after `patch()`.
140
+ */
141
+ instant(key: string, params?: MkTranslateParams): string;
142
+ /** Whether `key` exists in `lang` (default: the active language) or its fallback. */
143
+ has(key: string, lang?: string): boolean;
144
+ /**
145
+ * CLDR plural form: `keyBase.{zero|one|two|few|many|other}` picked with
146
+ * `Intl.PluralRules` for the active language, `other` as the fallback,
147
+ * interpolated with `{ count, ...params }`.
148
+ *
149
+ * ```json
150
+ * { "guests": { "one": "{{count}} osoba", "few": "{{count}} osoby", "many": "{{count}} osób", "other": "{{count}} osoby" } }
151
+ * ```
152
+ */
153
+ plural(keyBase: string, count: number, params?: MkTranslateParams): string;
154
+ /** The flat dictionary of `lang` (default: active), `{}` before it loads. */
155
+ translations(lang?: string): MkFlatTranslations;
156
+ /** Languages currently in memory. */
157
+ loadedLangs(): string[];
158
+ /**
159
+ * Merge strings into `lang` at runtime — a translation editor previewing
160
+ * an edit, or a late-arriving overrides payload. Nested or flat.
161
+ */
162
+ patch(lang: string, strings: MkTranslationTree | MkFlatTranslations): void;
163
+ /** Replace `lang` entirely (tests, editors reloading from source). */
164
+ set(lang: string, strings: MkTranslationTree | MkFlatTranslations): void;
165
+ private lookup;
166
+ private fetch;
167
+ private baseLoader;
168
+ private overridesLoaderOrNull;
169
+ private bump;
170
+ private recordMissing;
171
+ static ɵfac: i0.ɵɵFactoryDeclaration<MkTranslate, never>;
172
+ static ɵprov: i0.ɵɵInjectableDeclaration<MkTranslate>;
173
+ }
174
+
175
+ /**
176
+ * `translate` — the key's string in the active language, with `{{name}}`
177
+ * placeholders filled from `params`. Impure so a language switch (or a
178
+ * `patch()`) re-renders every use; the signal reads inside `instant()` mark
179
+ * the host view dirty, so this stays cheap under OnPush and zoneless.
180
+ *
181
+ * ```html
182
+ * {{ 'menu.title' | translate }}
183
+ * {{ 'cart.items' | translate: { count: 3 } }}
184
+ * ```
185
+ */
186
+ declare class MkTranslatePipe implements PipeTransform {
187
+ private readonly translate;
188
+ transform(key: string | null | undefined, params?: MkTranslateParams): string;
189
+ static ɵfac: i0.ɵɵFactoryDeclaration<MkTranslatePipe, never>;
190
+ static ɵpipe: i0.ɵɵPipeDeclaration<MkTranslatePipe, "translate", true>;
191
+ }
192
+ /**
193
+ * `translatePlural` — the CLDR plural form under `keyBase` for a count
194
+ * (see {@link MkTranslate.plural}), interpolated with `{ count, ...params }`.
195
+ *
196
+ * ```html
197
+ * {{ guests | translatePlural: 'reservation.guests' }} <!-- 2 osoby / 5 osób -->
198
+ * ```
199
+ */
200
+ declare class MkTranslatePluralPipe implements PipeTransform {
201
+ private readonly translate;
202
+ transform(count: number | string | null | undefined, keyBase: string, params?: MkTranslateParams): string;
203
+ static ɵfac: i0.ɵɵFactoryDeclaration<MkTranslatePluralPipe, never>;
204
+ static ɵpipe: i0.ɵɵPipeDeclaration<MkTranslatePluralPipe, "translatePlural", true>;
205
+ }
206
+ /**
207
+ * Everything a template needs, for `imports: [...MkTranslateImports]` — the
208
+ * one-line replacement for an ngx-translate `TranslateModule` import.
209
+ */
210
+ declare const MkTranslateImports: readonly [typeof MkTranslatePipe, typeof MkTranslatePluralPipe];
211
+
212
+ /** Options for {@link mkHttpTranslateLoader}. */
213
+ interface MkHttpTranslateLoaderOptions {
214
+ /** URL prefix; the language code is appended. Default `/assets/i18n/`. */
215
+ prefix?: string;
216
+ /** URL suffix after the language code. Default `.json`. */
217
+ suffix?: string;
218
+ }
219
+ /**
220
+ * Fetch `<prefix><lang><suffix>` with `HttpClient` — the bundled JSON files
221
+ * in `assets/i18n/`. Needs `provideHttpClient()`; SSR apps that read the
222
+ * files from disk can supply their own {@link MkTranslateLoader} instead.
223
+ */
224
+ declare function mkHttpTranslateLoader(options?: MkHttpTranslateLoaderOptions): MkTranslateLoaderFactory;
225
+ /**
226
+ * Strings given up front, keyed by language — tests, storybooks, tiny apps.
227
+ * A language not in the map resolves to `{}`.
228
+ */
229
+ declare function mkStaticTranslateLoader(byLang: Record<string, MkTranslationTree>): MkTranslateLoaderFactory;
230
+
231
+ /**
232
+ * Register app translations. By default the initial language is loaded
233
+ * before the first render (`preload`), so no view ever shows raw keys and
234
+ * nothing caches them.
235
+ *
236
+ * ```ts
237
+ * providers: [
238
+ * provideHttpClient(withFetch()),
239
+ * provideMkTranslate({
240
+ * lang: 'pl',
241
+ * fallbackLang: 'pl',
242
+ * loader: mkHttpTranslateLoader(),
243
+ * overrides: () => inject(TranslationOverridesApi), // optional
244
+ * }),
245
+ * ]
246
+ * ```
247
+ */
248
+ declare function provideMkTranslate(config: MkTranslateConfig): EnvironmentProviders;
249
+
250
+ export { MK_TRANSLATE_CONFIG, MkTranslate, MkTranslateImports, MkTranslatePipe, MkTranslatePluralPipe, mkFlattenTranslations, mkHttpTranslateLoader, mkInterpolate, mkStaticTranslateLoader, mkUnflattenTranslations, provideMkTranslate };
251
+ export type { MkFlatTranslations, MkHttpTranslateLoaderOptions, MkTranslateConfig, MkTranslateLoader, MkTranslateLoaderFactory, MkTranslateParams, MkTranslationTree };
@@ -14,6 +14,7 @@ export * from '@mk-kit/ui/table';
14
14
  export * from '@mk-kit/ui/status';
15
15
  export * from '@mk-kit/ui/data';
16
16
  export * from '@mk-kit/ui/kanban';
17
+ export * from '@mk-kit/ui/translate';
17
18
  export * from '@mk-kit/ui/feedback';
18
19
  export * from '@mk-kit/ui/rich-text';
19
20
  export * from '@mk-kit/ui/block-editor';