@mk-kit/ui 0.54.0 → 0.55.1

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,504 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, Injector, TransferState, PLATFORM_ID, signal, computed, isDevMode, makeStateKey, runInInjectionContext, Injectable, Pipe, provideAppInitializer, makeEnvironmentProviders } from '@angular/core';
3
+ import { isPlatformServer, DOCUMENT } from '@angular/common';
4
+ import { toObservable } from '@angular/core/rxjs-interop';
5
+ import { HttpClient } from '@angular/common/http';
6
+ import { firstValueFrom } from 'rxjs';
7
+
8
+ /** Configuration token; set by {@link provideMkTranslate}. */
9
+ const MK_TRANSLATE_CONFIG = new InjectionToken('MK_TRANSLATE_CONFIG');
10
+ const PLACEHOLDER = /\{\{\s*([\w.-]+)\s*\}\}/g;
11
+ /** `{ a: { b: 'x' } }` → `{ 'a.b': 'x' }`; already-dotted keys pass through. */
12
+ function mkFlattenTranslations(tree, prefix = '', out = {}) {
13
+ if (!tree)
14
+ return out;
15
+ for (const [k, v] of Object.entries(tree)) {
16
+ const key = prefix ? `${prefix}.${k}` : k;
17
+ if (v && typeof v === 'object')
18
+ mkFlattenTranslations(v, key, out);
19
+ else if (typeof v === 'string')
20
+ out[key] = v;
21
+ }
22
+ return out;
23
+ }
24
+ /** `{ 'a.b': 'x' }` → `{ a: { b: 'x' } }` — for editors that write files back. */
25
+ function mkUnflattenTranslations(flat) {
26
+ const tree = {};
27
+ for (const key of Object.keys(flat).sort()) {
28
+ const parts = key.split('.');
29
+ let node = tree;
30
+ for (let i = 0; i < parts.length - 1; i++) {
31
+ const next = node[parts[i]];
32
+ if (!next || typeof next !== 'object')
33
+ node[parts[i]] = {};
34
+ node = node[parts[i]];
35
+ }
36
+ node[parts[parts.length - 1]] = flat[key];
37
+ }
38
+ return tree;
39
+ }
40
+ /** Replace `{{name}}` placeholders; unknown names are left in place. */
41
+ function mkInterpolate(template, params) {
42
+ if (!params)
43
+ return template;
44
+ return template.replace(PLACEHOLDER, (match, name) => {
45
+ const value = name.split('.').reduce((acc, part) => (acc && typeof acc === 'object' ? acc[part] : undefined), params);
46
+ return value === undefined || value === null ? match : String(value);
47
+ });
48
+ }
49
+ /**
50
+ * App translations as signals: a `lang` you switch with `use()`, `instant()`
51
+ * for code, the `translate` pipe for templates, and `plural()` for CLDR
52
+ * count forms. Dictionaries are the plain nested JSON you already have; an
53
+ * optional overrides loader (a database of edits, say) is merged on top per
54
+ * language. On the server the loaded strings ride to the browser through
55
+ * `TransferState`, so hydration never refetches or flashes raw keys.
56
+ *
57
+ * ```ts
58
+ * provideMkTranslate({
59
+ * lang: 'pl',
60
+ * fallbackLang: 'pl',
61
+ * loader: mkHttpTranslateLoader({ prefix: '/assets/i18n/' }),
62
+ * });
63
+ * ```
64
+ * ```html
65
+ * {{ 'checkout.cart.total' | translate }}
66
+ * {{ 'checkout.cart.freeDeliveryMissing' | translate: { amount: 12 } }}
67
+ * ```
68
+ */
69
+ class MkTranslate {
70
+ config = inject(MK_TRANSLATE_CONFIG, { optional: true });
71
+ injector = inject(Injector);
72
+ transfer = inject(TransferState, { optional: true });
73
+ isServer = isPlatformServer(inject(PLATFORM_ID));
74
+ document = inject(DOCUMENT, { optional: true });
75
+ loader = null;
76
+ overridesLoader = null;
77
+ dictionaries = new Map();
78
+ declared = new Set();
79
+ /** Languages holding only the keys a server render used (see `transfer`). */
80
+ partial = new Set();
81
+ /** Keys read on the server, per language — what `transfer: 'used'` ships. */
82
+ used = new Map();
83
+ pending = new Map();
84
+ /** Bumped whenever a dictionary changes, so readers recompute. */
85
+ version = signal(0, /* @ts-ignore */
86
+ ...(ngDevMode ? [{ debugName: "version" }] : /* istanbul ignore next */ []));
87
+ // Missing keys are noticed while templates render, where writing a signal
88
+ // is forbidden (NG0600) — so the set is plain and a tick signal is bumped
89
+ // in a microtask, once per batch of misses.
90
+ missing = new Set();
91
+ missingTick = signal(0, /* @ts-ignore */
92
+ ...(ngDevMode ? [{ debugName: "missingTick" }] : /* istanbul ignore next */ []));
93
+ missingFlush = null;
94
+ /** The active language. Read it in a `computed()` to follow switches. */
95
+ lang = signal(this.config?.lang ?? 'en', /* @ts-ignore */
96
+ ...(ngDevMode ? [{ debugName: "lang" }] : /* istanbul ignore next */ []));
97
+ /** `true` once the active language's strings are in memory. */
98
+ ready = computed(() => {
99
+ this.version();
100
+ return this.dictionaries.has(this.lang());
101
+ }, /* @ts-ignore */
102
+ ...(ngDevMode ? [{ debugName: "ready" }] : /* istanbul ignore next */ []));
103
+ /** `lang` as an observable, for code still written around streams. */
104
+ langChange = toObservable(this.lang);
105
+ /** Keys asked for that neither the active nor the fallback language has. */
106
+ missingKeys = computed(() => {
107
+ this.missingTick();
108
+ return [...this.missing].sort();
109
+ }, /* @ts-ignore */
110
+ ...(ngDevMode ? [{ debugName: "missingKeys" }] : /* istanbul ignore next */ []));
111
+ constructor() {
112
+ if (!this.config && isDevMode()) {
113
+ console.warn('[mk-translate] provideMkTranslate() is missing — every key renders as itself.');
114
+ }
115
+ }
116
+ /** The active language as a plain string (for non-reactive call sites). */
117
+ getCurrentLang() {
118
+ return this.lang();
119
+ }
120
+ /** ngx-translate-compatible alias of {@link getCurrentLang}. */
121
+ get currentLang() {
122
+ return this.lang();
123
+ }
124
+ /** Languages known to the service: loaded ones plus any added with {@link addLangs}. */
125
+ getLangs() {
126
+ this.version();
127
+ return [...new Set([...this.declared, ...this.dictionaries.keys()])];
128
+ }
129
+ /** Declare languages up front (a switcher's list); loading still happens on `use()`. */
130
+ addLangs(langs) {
131
+ for (const lang of langs)
132
+ this.declared.add(lang);
133
+ this.bump();
134
+ }
135
+ /**
136
+ * ngx-translate-compatible alias: `setTranslation(lang, strings, true)`
137
+ * merges like {@link patch}, `false` (the default there) replaces like
138
+ * {@link set}.
139
+ */
140
+ setTranslation(lang, strings, shouldMerge = false) {
141
+ if (shouldMerge)
142
+ this.patch(lang, strings);
143
+ else
144
+ this.set(lang, strings);
145
+ }
146
+ /**
147
+ * Load `lang` (once — later calls are cached) and make it active. Resolves
148
+ * when the strings are in memory; a failed load rejects and leaves the
149
+ * previous language active.
150
+ */
151
+ use(lang) {
152
+ // A language already in memory switches synchronously — no microtask
153
+ // between the click and the re-render, and code that reads the service
154
+ // right after `use()` (tests, `computed()` setups) sees the new state.
155
+ const fallback = this.config?.fallbackLang;
156
+ const needsFallback = !!fallback && fallback !== lang && !this.dictionaries.has(fallback);
157
+ if (this.dictionaries.has(lang) && !needsFallback) {
158
+ this.activate(lang);
159
+ return Promise.resolve();
160
+ }
161
+ // The fallback rides along so that, once `use()` resolves, per-key
162
+ // fallback works too. Its failure never blocks the switch.
163
+ const fallbackLoad = needsFallback ? this.load(fallback).catch(() => undefined) : Promise.resolve();
164
+ return Promise.all([this.load(lang), fallbackLoad]).then(() => this.activate(lang));
165
+ }
166
+ activate(lang) {
167
+ this.lang.set(lang);
168
+ if (this.config?.documentLang !== false) {
169
+ this.document?.documentElement?.setAttribute('lang', lang);
170
+ }
171
+ }
172
+ /** Load a language into memory without switching to it. */
173
+ load(lang) {
174
+ if (this.dictionaries.has(lang))
175
+ return Promise.resolve();
176
+ let task = this.pending.get(lang);
177
+ if (!task) {
178
+ task = this.fetch(lang).finally(() => this.pending.delete(lang));
179
+ this.pending.set(lang, task);
180
+ }
181
+ return task;
182
+ }
183
+ /**
184
+ * Translate `key` in the active language, then the fallback; `{{name}}`
185
+ * placeholders come from `params`. A missing key renders as the key
186
+ * itself (or whatever `onMissing` returns) and is recorded in
187
+ * {@link missingKeys}. Reactive: reading it inside a template or a
188
+ * `computed()` re-runs on language switch and after `patch()`.
189
+ */
190
+ instant(key, params) {
191
+ const lang = this.lang();
192
+ this.version();
193
+ if (this.isServer)
194
+ this.noteUsed(lang, key);
195
+ const found = this.lookup(key, lang);
196
+ if (found === undefined) {
197
+ // A partial (hydration) dictionary is expected to lack keys until the
198
+ // background load merges — those are not misses.
199
+ if (!this.partial.has(lang))
200
+ this.recordMissing(key);
201
+ const replacement = this.config?.onMissing?.(key, lang);
202
+ return typeof replacement === 'string' ? replacement : key;
203
+ }
204
+ return mkInterpolate(found, params);
205
+ }
206
+ /** Whether `key` exists in `lang` (default: the active language) or its fallback. */
207
+ has(key, lang = this.lang()) {
208
+ this.version();
209
+ return this.lookup(key, lang) !== undefined;
210
+ }
211
+ /**
212
+ * CLDR plural form: `keyBase.{zero|one|two|few|many|other}` picked with
213
+ * `Intl.PluralRules` for the active language, `other` as the fallback,
214
+ * interpolated with `{ count, ...params }`.
215
+ *
216
+ * ```json
217
+ * { "guests": { "one": "{{count}} osoba", "few": "{{count}} osoby", "many": "{{count}} osób", "other": "{{count}} osoby" } }
218
+ * ```
219
+ */
220
+ plural(keyBase, count, params) {
221
+ const n = Number(count) || 0;
222
+ const lang = this.lang();
223
+ let category = 'other';
224
+ try {
225
+ category = new Intl.PluralRules(lang).select(n);
226
+ }
227
+ catch {
228
+ /* unknown locale → other */
229
+ }
230
+ const merged = { count: n, ...params };
231
+ const key = `${keyBase}.${category}`;
232
+ return this.has(key) ? this.instant(key, merged) : this.instant(`${keyBase}.other`, merged);
233
+ }
234
+ /** The flat dictionary of `lang` (default: active), `{}` before it loads. */
235
+ translations(lang = this.lang()) {
236
+ this.version();
237
+ return { ...(this.dictionaries.get(lang) ?? {}) };
238
+ }
239
+ /** Languages currently in memory. */
240
+ loadedLangs() {
241
+ this.version();
242
+ return [...this.dictionaries.keys()];
243
+ }
244
+ /**
245
+ * Merge strings into `lang` at runtime — a translation editor previewing
246
+ * an edit, or a late-arriving overrides payload. Nested or flat.
247
+ */
248
+ patch(lang, strings) {
249
+ const current = this.dictionaries.get(lang) ?? {};
250
+ this.dictionaries.set(lang, { ...current, ...mkFlattenTranslations(strings) });
251
+ this.bump();
252
+ }
253
+ /** Replace `lang` entirely (tests, editors reloading from source). */
254
+ set(lang, strings) {
255
+ this.dictionaries.set(lang, mkFlattenTranslations(strings));
256
+ this.bump();
257
+ }
258
+ // ── internals ────────────────────────────────────────────────────────────
259
+ lookup(key, lang) {
260
+ const direct = this.dictionaries.get(lang)?.[key];
261
+ if (direct !== undefined)
262
+ return direct;
263
+ const fallback = this.config?.fallbackLang;
264
+ if (fallback && fallback !== lang)
265
+ return this.dictionaries.get(fallback)?.[key];
266
+ return undefined;
267
+ }
268
+ async fetch(lang) {
269
+ const stateKey = makeStateKey(`mk-translate:${lang}`);
270
+ // Hydration: the server already loaded (some of) this language.
271
+ if (!this.isServer && this.transfer?.hasKey(stateKey)) {
272
+ const payload = this.transfer.get(stateKey, { strings: {}, partial: false });
273
+ this.transfer.remove(stateKey);
274
+ this.dictionaries.set(lang, payload.strings);
275
+ if (payload.partial) {
276
+ // Enough to hydrate without a flash; the rest arrives in the
277
+ // background and merges under the same keys.
278
+ this.partial.add(lang);
279
+ void this.fetchFull(lang)
280
+ .then((flat) => {
281
+ this.dictionaries.set(lang, { ...flat, ...this.dictionaries.get(lang) });
282
+ this.partial.delete(lang);
283
+ this.bump();
284
+ })
285
+ .catch((err) => {
286
+ if (isDevMode())
287
+ console.warn(`[mk-translate] background load of "${lang}" failed`, err);
288
+ });
289
+ }
290
+ this.bump();
291
+ return;
292
+ }
293
+ if (!this.config) {
294
+ this.dictionaries.set(lang, {});
295
+ this.bump();
296
+ return;
297
+ }
298
+ const flat = await this.fetchFull(lang);
299
+ this.dictionaries.set(lang, flat);
300
+ if (this.isServer && this.transfer)
301
+ this.serialize(lang, stateKey, flat);
302
+ this.bump();
303
+ }
304
+ /** Base + overrides for `lang`, flattened. */
305
+ async fetchFull(lang) {
306
+ const base = mkFlattenTranslations(await this.baseLoader().load(lang));
307
+ let overrides = {};
308
+ const overridesLoader = this.overridesLoaderOrNull();
309
+ if (overridesLoader) {
310
+ try {
311
+ overrides = mkFlattenTranslations(await overridesLoader.load(lang));
312
+ }
313
+ catch (err) {
314
+ if (isDevMode())
315
+ console.warn(`[mk-translate] overrides for "${lang}" failed to load`, err);
316
+ }
317
+ }
318
+ return { ...base, ...overrides };
319
+ }
320
+ /** Server: decide what rides to the browser (see `MkTranslateConfig.transfer`). */
321
+ serialize(lang, stateKey, flat) {
322
+ const mode = this.config?.transfer ?? 'used';
323
+ if (mode === 'none' || !this.transfer)
324
+ return;
325
+ if (mode === 'all') {
326
+ this.transfer.set(stateKey, { strings: flat, partial: false });
327
+ return;
328
+ }
329
+ // 'used': resolved lazily when the page serialises, after every
330
+ // template ran — only the keys this render actually read.
331
+ this.transfer.onSerialize(stateKey, () => {
332
+ const keys = this.used.get(lang);
333
+ const strings = {};
334
+ if (keys)
335
+ for (const k of keys)
336
+ if (flat[k] !== undefined)
337
+ strings[k] = flat[k];
338
+ return { strings, partial: true };
339
+ });
340
+ }
341
+ noteUsed(lang, key) {
342
+ let set = this.used.get(lang);
343
+ if (!set)
344
+ this.used.set(lang, (set = new Set()));
345
+ set.add(key);
346
+ const fallback = this.config?.fallbackLang;
347
+ if (fallback && fallback !== lang) {
348
+ let fb = this.used.get(fallback);
349
+ if (!fb)
350
+ this.used.set(fallback, (fb = new Set()));
351
+ fb.add(key);
352
+ }
353
+ }
354
+ /** `true` while `lang` holds only a server render's keys and the rest is still loading. */
355
+ isPartial(lang = this.lang()) {
356
+ this.version();
357
+ return this.partial.has(lang);
358
+ }
359
+ baseLoader() {
360
+ if (!this.loader) {
361
+ this.loader = runInInjectionContext(this.injector, () => this.config.loader());
362
+ }
363
+ return this.loader;
364
+ }
365
+ overridesLoaderOrNull() {
366
+ const factory = this.config?.overrides;
367
+ if (!factory)
368
+ return null;
369
+ if (!this.overridesLoader) {
370
+ this.overridesLoader = runInInjectionContext(this.injector, factory);
371
+ }
372
+ return this.overridesLoader;
373
+ }
374
+ bump() {
375
+ this.version.update((v) => v + 1);
376
+ }
377
+ recordMissing(key) {
378
+ if (this.missing.has(key))
379
+ return;
380
+ this.missing.add(key);
381
+ this.missingFlush ??= Promise.resolve().then(() => {
382
+ this.missingFlush = null;
383
+ this.missingTick.update((v) => v + 1);
384
+ });
385
+ }
386
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkTranslate, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
387
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkTranslate, providedIn: 'root' });
388
+ }
389
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkTranslate, decorators: [{
390
+ type: Injectable,
391
+ args: [{ providedIn: 'root' }]
392
+ }], ctorParameters: () => [] });
393
+
394
+ /**
395
+ * `translate` — the key's string in the active language, with `{{name}}`
396
+ * placeholders filled from `params`. Impure so a language switch (or a
397
+ * `patch()`) re-renders every use; the signal reads inside `instant()` mark
398
+ * the host view dirty, so this stays cheap under OnPush and zoneless.
399
+ *
400
+ * ```html
401
+ * {{ 'menu.title' | translate }}
402
+ * {{ 'cart.items' | translate: { count: 3 } }}
403
+ * ```
404
+ */
405
+ class MkTranslatePipe {
406
+ translate = inject(MkTranslate);
407
+ transform(key, params) {
408
+ if (!key)
409
+ return '';
410
+ return this.translate.instant(key, params);
411
+ }
412
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkTranslatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
413
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: MkTranslatePipe, isStandalone: true, name: "translate", pure: false });
414
+ }
415
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkTranslatePipe, decorators: [{
416
+ type: Pipe,
417
+ args: [{ name: 'translate', pure: false }]
418
+ }] });
419
+ /**
420
+ * `translatePlural` — the CLDR plural form under `keyBase` for a count
421
+ * (see {@link MkTranslate.plural}), interpolated with `{ count, ...params }`.
422
+ *
423
+ * ```html
424
+ * {{ guests | translatePlural: 'reservation.guests' }} <!-- 2 osoby / 5 osób -->
425
+ * ```
426
+ */
427
+ class MkTranslatePluralPipe {
428
+ translate = inject(MkTranslate);
429
+ transform(count, keyBase, params) {
430
+ return this.translate.plural(keyBase, Number(count) || 0, params);
431
+ }
432
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkTranslatePluralPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
433
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: MkTranslatePluralPipe, isStandalone: true, name: "translatePlural", pure: false });
434
+ }
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkTranslatePluralPipe, decorators: [{
436
+ type: Pipe,
437
+ args: [{ name: 'translatePlural', pure: false }]
438
+ }] });
439
+ /**
440
+ * Everything a template needs, for `imports: [...MkTranslateImports]` — the
441
+ * one-line replacement for an ngx-translate `TranslateModule` import.
442
+ */
443
+ const MkTranslateImports = [MkTranslatePipe, MkTranslatePluralPipe];
444
+
445
+ /**
446
+ * Fetch `<prefix><lang><suffix>` with `HttpClient` — the bundled JSON files
447
+ * in `assets/i18n/`. Needs `provideHttpClient()`; SSR apps that read the
448
+ * files from disk can supply their own {@link MkTranslateLoader} instead.
449
+ */
450
+ function mkHttpTranslateLoader(options = {}) {
451
+ const { prefix = '/assets/i18n/', suffix = '.json' } = options;
452
+ return () => {
453
+ const http = inject(HttpClient);
454
+ return {
455
+ load: (lang) => firstValueFrom(http.get(`${prefix}${lang}${suffix}`)),
456
+ };
457
+ };
458
+ }
459
+ /**
460
+ * Strings given up front, keyed by language — tests, storybooks, tiny apps.
461
+ * A language not in the map resolves to `{}`.
462
+ */
463
+ function mkStaticTranslateLoader(byLang) {
464
+ return () => ({ load: (lang) => byLang[lang] ?? {} });
465
+ }
466
+
467
+ /**
468
+ * Register app translations. By default the initial language is loaded
469
+ * before the first render (`preload`), so no view ever shows raw keys and
470
+ * nothing caches them.
471
+ *
472
+ * ```ts
473
+ * providers: [
474
+ * provideHttpClient(withFetch()),
475
+ * provideMkTranslate({
476
+ * lang: 'pl',
477
+ * fallbackLang: 'pl',
478
+ * loader: mkHttpTranslateLoader(),
479
+ * overrides: () => inject(TranslationOverridesApi), // optional
480
+ * }),
481
+ * ]
482
+ * ```
483
+ */
484
+ function provideMkTranslate(config) {
485
+ const providers = [
486
+ { provide: MK_TRANSLATE_CONFIG, useValue: config },
487
+ ];
488
+ if (config.preload !== false) {
489
+ providers.push(provideAppInitializer(() => inject(MkTranslate)
490
+ .use(config.lang)
491
+ .catch((err) => {
492
+ // A broken file must not blank the app — keys render as themselves.
493
+ console.error(`[mk-translate] "${config.lang}" failed to load before first render`, err);
494
+ })));
495
+ }
496
+ return makeEnvironmentProviders(providers);
497
+ }
498
+
499
+ /**
500
+ * Generated bundle index. Do not edit.
501
+ */
502
+
503
+ export { MK_TRANSLATE_CONFIG, MkTranslate, MkTranslateImports, MkTranslatePipe, MkTranslatePluralPipe, mkFlattenTranslations, mkHttpTranslateLoader, mkInterpolate, mkStaticTranslateLoader, mkUnflattenTranslations, provideMkTranslate };
504
+ //# sourceMappingURL=mk-kit-ui-translate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mk-kit-ui-translate.mjs","sources":["../../../projects/mk-kit/translate/translate.service.ts","../../../projects/mk-kit/translate/translate.pipe.ts","../../../projects/mk-kit/translate/translate.loaders.ts","../../../projects/mk-kit/translate/translate.providers.ts","../../../projects/mk-kit/translate/mk-kit-ui-translate.ts"],"sourcesContent":["import {\n computed,\n inject,\n Injectable,\n InjectionToken,\n Injector,\n isDevMode,\n makeStateKey,\n PLATFORM_ID,\n runInInjectionContext,\n signal,\n TransferState,\n} from '@angular/core';\nimport { DOCUMENT, isPlatformServer } from '@angular/common';\nimport { toObservable } from '@angular/core/rxjs-interop';\nimport type {\n MkFlatTranslations,\n MkTranslateConfig,\n MkTranslateLoader,\n MkTranslateParams,\n MkTranslationTree,\n} from './translate.types';\n\n/** Configuration token; set by {@link provideMkTranslate}. */\nexport const MK_TRANSLATE_CONFIG = new InjectionToken<MkTranslateConfig>('MK_TRANSLATE_CONFIG');\n\nconst PLACEHOLDER = /\\{\\{\\s*([\\w.-]+)\\s*\\}\\}/g;\n\n/** What a server render hands to the browser for one language. */\ninterface MkTransferPayload {\n strings: MkFlatTranslations;\n /** Only the keys the render used — the rest is loading in the background. */\n partial: boolean;\n}\n\n/** `{ a: { b: 'x' } }` → `{ 'a.b': 'x' }`; already-dotted keys pass through. */\nexport function mkFlattenTranslations(\n tree: MkTranslationTree | null | undefined,\n prefix = '',\n out: MkFlatTranslations = {},\n): MkFlatTranslations {\n if (!tree) return out;\n for (const [k, v] of Object.entries(tree)) {\n const key = prefix ? `${prefix}.${k}` : k;\n if (v && typeof v === 'object') mkFlattenTranslations(v, key, out);\n else if (typeof v === 'string') out[key] = v;\n }\n return out;\n}\n\n/** `{ 'a.b': 'x' }` → `{ a: { b: 'x' } }` — for editors that write files back. */\nexport function mkUnflattenTranslations(flat: MkFlatTranslations): MkTranslationTree {\n const tree: MkTranslationTree = {};\n for (const key of Object.keys(flat).sort()) {\n const parts = key.split('.');\n let node = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n const next = node[parts[i]];\n if (!next || typeof next !== 'object') node[parts[i]] = {};\n node = node[parts[i]] as MkTranslationTree;\n }\n node[parts[parts.length - 1]] = flat[key];\n }\n return tree;\n}\n\n/** Replace `{{name}}` placeholders; unknown names are left in place. */\nexport function mkInterpolate(template: string, params?: MkTranslateParams): string {\n if (!params) return template;\n return template.replace(PLACEHOLDER, (match, name: string) => {\n const value = name.split('.').reduce<unknown>(\n (acc, part) => (acc && typeof acc === 'object' ? (acc as Record<string, unknown>)[part] : undefined),\n params,\n );\n return value === undefined || value === null ? match : String(value);\n });\n}\n\n/**\n * App translations as signals: a `lang` you switch with `use()`, `instant()`\n * for code, the `translate` pipe for templates, and `plural()` for CLDR\n * count forms. Dictionaries are the plain nested JSON you already have; an\n * optional overrides loader (a database of edits, say) is merged on top per\n * language. On the server the loaded strings ride to the browser through\n * `TransferState`, so hydration never refetches or flashes raw keys.\n *\n * ```ts\n * provideMkTranslate({\n * lang: 'pl',\n * fallbackLang: 'pl',\n * loader: mkHttpTranslateLoader({ prefix: '/assets/i18n/' }),\n * });\n * ```\n * ```html\n * {{ 'checkout.cart.total' | translate }}\n * {{ 'checkout.cart.freeDeliveryMissing' | translate: { amount: 12 } }}\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class MkTranslate {\n private readonly config = inject(MK_TRANSLATE_CONFIG, { optional: true });\n private readonly injector = inject(Injector);\n private readonly transfer = inject(TransferState, { optional: true });\n private readonly isServer = isPlatformServer(inject(PLATFORM_ID));\n private readonly document = inject(DOCUMENT, { optional: true });\n\n private loader: MkTranslateLoader | null = null;\n private overridesLoader: MkTranslateLoader | null = null;\n private readonly dictionaries = new Map<string, MkFlatTranslations>();\n private readonly declared = new Set<string>();\n /** Languages holding only the keys a server render used (see `transfer`). */\n private readonly partial = new Set<string>();\n /** Keys read on the server, per language — what `transfer: 'used'` ships. */\n private readonly used = new Map<string, Set<string>>();\n private readonly pending = new Map<string, Promise<void>>();\n /** Bumped whenever a dictionary changes, so readers recompute. */\n private readonly version = signal(0);\n // Missing keys are noticed while templates render, where writing a signal\n // is forbidden (NG0600) — so the set is plain and a tick signal is bumped\n // in a microtask, once per batch of misses.\n private readonly missing = new Set<string>();\n private readonly missingTick = signal(0);\n private missingFlush: Promise<void> | null = null;\n\n /** The active language. Read it in a `computed()` to follow switches. */\n readonly lang = signal<string>(this.config?.lang ?? 'en');\n /** `true` once the active language's strings are in memory. */\n readonly ready = computed(() => {\n this.version();\n return this.dictionaries.has(this.lang());\n });\n /** `lang` as an observable, for code still written around streams. */\n readonly langChange = toObservable(this.lang);\n /** Keys asked for that neither the active nor the fallback language has. */\n readonly missingKeys = computed(() => {\n this.missingTick();\n return [...this.missing].sort();\n });\n\n constructor() {\n if (!this.config && isDevMode()) {\n console.warn('[mk-translate] provideMkTranslate() is missing — every key renders as itself.');\n }\n }\n\n /** The active language as a plain string (for non-reactive call sites). */\n getCurrentLang(): string {\n return this.lang();\n }\n\n /** ngx-translate-compatible alias of {@link getCurrentLang}. */\n get currentLang(): string {\n return this.lang();\n }\n\n /** Languages known to the service: loaded ones plus any added with {@link addLangs}. */\n getLangs(): string[] {\n this.version();\n return [...new Set([...this.declared, ...this.dictionaries.keys()])];\n }\n\n /** Declare languages up front (a switcher's list); loading still happens on `use()`. */\n addLangs(langs: string[]): void {\n for (const lang of langs) this.declared.add(lang);\n this.bump();\n }\n\n /**\n * ngx-translate-compatible alias: `setTranslation(lang, strings, true)`\n * merges like {@link patch}, `false` (the default there) replaces like\n * {@link set}.\n */\n setTranslation(lang: string, strings: MkTranslationTree | MkFlatTranslations, shouldMerge = false): void {\n if (shouldMerge) this.patch(lang, strings);\n else this.set(lang, strings);\n }\n\n /**\n * Load `lang` (once — later calls are cached) and make it active. Resolves\n * when the strings are in memory; a failed load rejects and leaves the\n * previous language active.\n */\n use(lang: string): Promise<void> {\n // A language already in memory switches synchronously — no microtask\n // between the click and the re-render, and code that reads the service\n // right after `use()` (tests, `computed()` setups) sees the new state.\n const fallback = this.config?.fallbackLang;\n const needsFallback = !!fallback && fallback !== lang && !this.dictionaries.has(fallback);\n if (this.dictionaries.has(lang) && !needsFallback) {\n this.activate(lang);\n return Promise.resolve();\n }\n // The fallback rides along so that, once `use()` resolves, per-key\n // fallback works too. Its failure never blocks the switch.\n const fallbackLoad = needsFallback ? this.load(fallback!).catch(() => undefined) : Promise.resolve();\n return Promise.all([this.load(lang), fallbackLoad]).then(() => this.activate(lang));\n }\n\n private activate(lang: string): void {\n this.lang.set(lang);\n if (this.config?.documentLang !== false) {\n this.document?.documentElement?.setAttribute('lang', lang);\n }\n }\n\n /** Load a language into memory without switching to it. */\n load(lang: string): Promise<void> {\n if (this.dictionaries.has(lang)) return Promise.resolve();\n let task = this.pending.get(lang);\n if (!task) {\n task = this.fetch(lang).finally(() => this.pending.delete(lang));\n this.pending.set(lang, task);\n }\n return task;\n }\n\n /**\n * Translate `key` in the active language, then the fallback; `{{name}}`\n * placeholders come from `params`. A missing key renders as the key\n * itself (or whatever `onMissing` returns) and is recorded in\n * {@link missingKeys}. Reactive: reading it inside a template or a\n * `computed()` re-runs on language switch and after `patch()`.\n */\n instant(key: string, params?: MkTranslateParams): string {\n const lang = this.lang();\n this.version();\n if (this.isServer) this.noteUsed(lang, key);\n const found = this.lookup(key, lang);\n if (found === undefined) {\n // A partial (hydration) dictionary is expected to lack keys until the\n // background load merges — those are not misses.\n if (!this.partial.has(lang)) this.recordMissing(key);\n const replacement = this.config?.onMissing?.(key, lang);\n return typeof replacement === 'string' ? replacement : key;\n }\n return mkInterpolate(found, params);\n }\n\n /** Whether `key` exists in `lang` (default: the active language) or its fallback. */\n has(key: string, lang = this.lang()): boolean {\n this.version();\n return this.lookup(key, lang) !== undefined;\n }\n\n /**\n * CLDR plural form: `keyBase.{zero|one|two|few|many|other}` picked with\n * `Intl.PluralRules` for the active language, `other` as the fallback,\n * interpolated with `{ count, ...params }`.\n *\n * ```json\n * { \"guests\": { \"one\": \"{{count}} osoba\", \"few\": \"{{count}} osoby\", \"many\": \"{{count}} osób\", \"other\": \"{{count}} osoby\" } }\n * ```\n */\n plural(keyBase: string, count: number, params?: MkTranslateParams): string {\n const n = Number(count) || 0;\n const lang = this.lang();\n let category: string = 'other';\n try {\n category = new Intl.PluralRules(lang).select(n);\n } catch {\n /* unknown locale → other */\n }\n const merged = { count: n, ...params };\n const key = `${keyBase}.${category}`;\n return this.has(key) ? this.instant(key, merged) : this.instant(`${keyBase}.other`, merged);\n }\n\n /** The flat dictionary of `lang` (default: active), `{}` before it loads. */\n translations(lang = this.lang()): MkFlatTranslations {\n this.version();\n return { ...(this.dictionaries.get(lang) ?? {}) };\n }\n\n /** Languages currently in memory. */\n loadedLangs(): string[] {\n this.version();\n return [...this.dictionaries.keys()];\n }\n\n /**\n * Merge strings into `lang` at runtime — a translation editor previewing\n * an edit, or a late-arriving overrides payload. Nested or flat.\n */\n patch(lang: string, strings: MkTranslationTree | MkFlatTranslations): void {\n const current = this.dictionaries.get(lang) ?? {};\n this.dictionaries.set(lang, { ...current, ...mkFlattenTranslations(strings as MkTranslationTree) });\n this.bump();\n }\n\n /** Replace `lang` entirely (tests, editors reloading from source). */\n set(lang: string, strings: MkTranslationTree | MkFlatTranslations): void {\n this.dictionaries.set(lang, mkFlattenTranslations(strings as MkTranslationTree));\n this.bump();\n }\n\n // ── internals ────────────────────────────────────────────────────────────\n\n private lookup(key: string, lang: string): string | undefined {\n const direct = this.dictionaries.get(lang)?.[key];\n if (direct !== undefined) return direct;\n const fallback = this.config?.fallbackLang;\n if (fallback && fallback !== lang) return this.dictionaries.get(fallback)?.[key];\n return undefined;\n }\n\n private async fetch(lang: string): Promise<void> {\n const stateKey = makeStateKey<MkTransferPayload>(`mk-translate:${lang}`);\n // Hydration: the server already loaded (some of) this language.\n if (!this.isServer && this.transfer?.hasKey(stateKey)) {\n const payload = this.transfer.get(stateKey, { strings: {}, partial: false });\n this.transfer.remove(stateKey);\n this.dictionaries.set(lang, payload.strings);\n if (payload.partial) {\n // Enough to hydrate without a flash; the rest arrives in the\n // background and merges under the same keys.\n this.partial.add(lang);\n void this.fetchFull(lang)\n .then((flat) => {\n this.dictionaries.set(lang, { ...flat, ...this.dictionaries.get(lang) });\n this.partial.delete(lang);\n this.bump();\n })\n .catch((err) => {\n if (isDevMode()) console.warn(`[mk-translate] background load of \"${lang}\" failed`, err);\n });\n }\n this.bump();\n return;\n }\n if (!this.config) {\n this.dictionaries.set(lang, {});\n this.bump();\n return;\n }\n const flat = await this.fetchFull(lang);\n this.dictionaries.set(lang, flat);\n if (this.isServer && this.transfer) this.serialize(lang, stateKey, flat);\n this.bump();\n }\n\n /** Base + overrides for `lang`, flattened. */\n private async fetchFull(lang: string): Promise<MkFlatTranslations> {\n const base = mkFlattenTranslations(await this.baseLoader().load(lang));\n let overrides: MkFlatTranslations = {};\n const overridesLoader = this.overridesLoaderOrNull();\n if (overridesLoader) {\n try {\n overrides = mkFlattenTranslations(await overridesLoader.load(lang));\n } catch (err) {\n if (isDevMode()) console.warn(`[mk-translate] overrides for \"${lang}\" failed to load`, err);\n }\n }\n return { ...base, ...overrides };\n }\n\n /** Server: decide what rides to the browser (see `MkTranslateConfig.transfer`). */\n private serialize(lang: string, stateKey: ReturnType<typeof makeStateKey<MkTransferPayload>>, flat: MkFlatTranslations): void {\n const mode = this.config?.transfer ?? 'used';\n if (mode === 'none' || !this.transfer) return;\n if (mode === 'all') {\n this.transfer.set(stateKey, { strings: flat, partial: false });\n return;\n }\n // 'used': resolved lazily when the page serialises, after every\n // template ran — only the keys this render actually read.\n this.transfer.onSerialize(stateKey, () => {\n const keys = this.used.get(lang);\n const strings: MkFlatTranslations = {};\n if (keys) for (const k of keys) if (flat[k] !== undefined) strings[k] = flat[k];\n return { strings, partial: true };\n });\n }\n\n private noteUsed(lang: string, key: string): void {\n let set = this.used.get(lang);\n if (!set) this.used.set(lang, (set = new Set()));\n set.add(key);\n const fallback = this.config?.fallbackLang;\n if (fallback && fallback !== lang) {\n let fb = this.used.get(fallback);\n if (!fb) this.used.set(fallback, (fb = new Set()));\n fb.add(key);\n }\n }\n\n /** `true` while `lang` holds only a server render's keys and the rest is still loading. */\n isPartial(lang = this.lang()): boolean {\n this.version();\n return this.partial.has(lang);\n }\n\n private baseLoader(): MkTranslateLoader {\n if (!this.loader) {\n this.loader = runInInjectionContext(this.injector, () => this.config!.loader());\n }\n return this.loader;\n }\n\n private overridesLoaderOrNull(): MkTranslateLoader | null {\n const factory = this.config?.overrides;\n if (!factory) return null;\n if (!this.overridesLoader) {\n this.overridesLoader = runInInjectionContext(this.injector, factory);\n }\n return this.overridesLoader;\n }\n\n private bump(): void {\n this.version.update((v) => v + 1);\n }\n\n private recordMissing(key: string): void {\n if (this.missing.has(key)) return;\n this.missing.add(key);\n this.missingFlush ??= Promise.resolve().then(() => {\n this.missingFlush = null;\n this.missingTick.update((v) => v + 1);\n });\n }\n}\n","import { inject, Pipe, type PipeTransform } from '@angular/core';\nimport { MkTranslate } from './translate.service';\nimport type { MkTranslateParams } from './translate.types';\n\n/**\n * `translate` — the key's string in the active language, with `{{name}}`\n * placeholders filled from `params`. Impure so a language switch (or a\n * `patch()`) re-renders every use; the signal reads inside `instant()` mark\n * the host view dirty, so this stays cheap under OnPush and zoneless.\n *\n * ```html\n * {{ 'menu.title' | translate }}\n * {{ 'cart.items' | translate: { count: 3 } }}\n * ```\n */\n@Pipe({ name: 'translate', pure: false })\nexport class MkTranslatePipe implements PipeTransform {\n private readonly translate = inject(MkTranslate);\n\n transform(key: string | null | undefined, params?: MkTranslateParams): string {\n if (!key) return '';\n return this.translate.instant(key, params);\n }\n}\n\n/**\n * `translatePlural` — the CLDR plural form under `keyBase` for a count\n * (see {@link MkTranslate.plural}), interpolated with `{ count, ...params }`.\n *\n * ```html\n * {{ guests | translatePlural: 'reservation.guests' }} <!-- 2 osoby / 5 osób -->\n * ```\n */\n@Pipe({ name: 'translatePlural', pure: false })\nexport class MkTranslatePluralPipe implements PipeTransform {\n private readonly translate = inject(MkTranslate);\n\n transform(count: number | string | null | undefined, keyBase: string, params?: MkTranslateParams): string {\n return this.translate.plural(keyBase, Number(count) || 0, params);\n }\n}\n\n/**\n * Everything a template needs, for `imports: [...MkTranslateImports]` — the\n * one-line replacement for an ngx-translate `TranslateModule` import.\n */\nexport const MkTranslateImports = [MkTranslatePipe, MkTranslatePluralPipe] as const;\n","import { inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { firstValueFrom } from 'rxjs';\nimport type { MkTranslateLoaderFactory, MkTranslationTree } from './translate.types';\n\n/** Options for {@link mkHttpTranslateLoader}. */\nexport interface MkHttpTranslateLoaderOptions {\n /** URL prefix; the language code is appended. Default `/assets/i18n/`. */\n prefix?: string;\n /** URL suffix after the language code. Default `.json`. */\n suffix?: string;\n}\n\n/**\n * Fetch `<prefix><lang><suffix>` with `HttpClient` — the bundled JSON files\n * in `assets/i18n/`. Needs `provideHttpClient()`; SSR apps that read the\n * files from disk can supply their own {@link MkTranslateLoader} instead.\n */\nexport function mkHttpTranslateLoader(\n options: MkHttpTranslateLoaderOptions = {},\n): MkTranslateLoaderFactory {\n const { prefix = '/assets/i18n/', suffix = '.json' } = options;\n return () => {\n const http = inject(HttpClient);\n return {\n load: (lang: string) => firstValueFrom(http.get<MkTranslationTree>(`${prefix}${lang}${suffix}`)),\n };\n };\n}\n\n/**\n * Strings given up front, keyed by language — tests, storybooks, tiny apps.\n * A language not in the map resolves to `{}`.\n */\nexport function mkStaticTranslateLoader(\n byLang: Record<string, MkTranslationTree>,\n): MkTranslateLoaderFactory {\n return () => ({ load: (lang: string) => byLang[lang] ?? {} });\n}\n","import {\n type EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n provideAppInitializer,\n} from '@angular/core';\nimport { MK_TRANSLATE_CONFIG, MkTranslate } from './translate.service';\nimport type { MkTranslateConfig } from './translate.types';\n\n/**\n * Register app translations. By default the initial language is loaded\n * before the first render (`preload`), so no view ever shows raw keys and\n * nothing caches them.\n *\n * ```ts\n * providers: [\n * provideHttpClient(withFetch()),\n * provideMkTranslate({\n * lang: 'pl',\n * fallbackLang: 'pl',\n * loader: mkHttpTranslateLoader(),\n * overrides: () => inject(TranslationOverridesApi), // optional\n * }),\n * ]\n * ```\n */\nexport function provideMkTranslate(config: MkTranslateConfig): EnvironmentProviders {\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n { provide: MK_TRANSLATE_CONFIG, useValue: config },\n ];\n if (config.preload !== false) {\n providers.push(\n provideAppInitializer(() =>\n inject(MkTranslate)\n .use(config.lang)\n .catch((err: unknown) => {\n // A broken file must not blank the app — keys render as themselves.\n console.error(`[mk-translate] \"${config.lang}\" failed to load before first render`, err);\n }),\n ),\n );\n }\n return makeEnvironmentProviders(providers);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -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';
@@ -1 +1 @@
1
- {"version":3,"file":"mk-kit-ui.mjs","sources":["../../../projects/mk-kit/src/public-api.ts","../../../projects/mk-kit/src/mk-kit-ui.ts"],"sourcesContent":["/*\n * Public API Surface of @mk-kit/ui.\n *\n * The library ships Material-style secondary entry points — import from the\n * group entries (`@mk-kit/ui/forms`, `@mk-kit/ui/table`, …) so a code-split\n * app only carries the groups each chunk uses. This root entry re-exports\n * everything for convenience; importing it eagerly pulls all groups into the\n * importing chunk.\n */\nexport * from '@mk-kit/ui/core';\nexport * from '@mk-kit/ui/core/signal-forms';\nexport * from '@mk-kit/ui/icon';\nexport * from '@mk-kit/ui/icon/extended';\nexport * from '@mk-kit/ui/chip';\nexport * from '@mk-kit/ui/checkbox';\nexport * from '@mk-kit/ui/button';\nexport * from '@mk-kit/ui/directives';\nexport * from '@mk-kit/ui/dnd';\nexport * from '@mk-kit/ui/navigation';\nexport * from '@mk-kit/ui/forms';\nexport * from '@mk-kit/ui/datetime';\nexport * from '@mk-kit/ui/table';\nexport * from '@mk-kit/ui/status';\nexport * from '@mk-kit/ui/data';\nexport * from '@mk-kit/ui/kanban';\nexport * from '@mk-kit/ui/feedback';\nexport * from '@mk-kit/ui/rich-text';\nexport * from '@mk-kit/ui/block-editor';\nexport * from '@mk-kit/ui/context-menu';\nexport * from '@mk-kit/ui/layout';\nexport * from '@mk-kit/ui/chat';\nexport * from '@mk-kit/ui/query-builder';\nexport * from '@mk-kit/ui/dynamic-form';\nexport * from '@mk-kit/ui/media';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAQG;;ACRH;;AAEG"}
1
+ {"version":3,"file":"mk-kit-ui.mjs","sources":["../../../projects/mk-kit/src/public-api.ts","../../../projects/mk-kit/src/mk-kit-ui.ts"],"sourcesContent":["/*\n * Public API Surface of @mk-kit/ui.\n *\n * The library ships Material-style secondary entry points — import from the\n * group entries (`@mk-kit/ui/forms`, `@mk-kit/ui/table`, …) so a code-split\n * app only carries the groups each chunk uses. This root entry re-exports\n * everything for convenience; importing it eagerly pulls all groups into the\n * importing chunk.\n */\nexport * from '@mk-kit/ui/core';\nexport * from '@mk-kit/ui/core/signal-forms';\nexport * from '@mk-kit/ui/icon';\nexport * from '@mk-kit/ui/icon/extended';\nexport * from '@mk-kit/ui/chip';\nexport * from '@mk-kit/ui/checkbox';\nexport * from '@mk-kit/ui/button';\nexport * from '@mk-kit/ui/directives';\nexport * from '@mk-kit/ui/dnd';\nexport * from '@mk-kit/ui/navigation';\nexport * from '@mk-kit/ui/forms';\nexport * from '@mk-kit/ui/datetime';\nexport * from '@mk-kit/ui/table';\nexport * from '@mk-kit/ui/status';\nexport * from '@mk-kit/ui/data';\nexport * from '@mk-kit/ui/kanban';\nexport * from '@mk-kit/ui/translate';\nexport * from '@mk-kit/ui/feedback';\nexport * from '@mk-kit/ui/rich-text';\nexport * from '@mk-kit/ui/block-editor';\nexport * from '@mk-kit/ui/context-menu';\nexport * from '@mk-kit/ui/layout';\nexport * from '@mk-kit/ui/chat';\nexport * from '@mk-kit/ui/query-builder';\nexport * from '@mk-kit/ui/dynamic-form';\nexport * from '@mk-kit/ui/media';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;AAQG;;ACRH;;AAEG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mk-kit/ui",
3
- "version": "0.54.0",
3
+ "version": "0.55.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -50,6 +50,10 @@
50
50
  "style": "./styles/mk-kit.css",
51
51
  "default": "./styles/mk-kit.css"
52
52
  },
53
+ "./presets/momentum.css": {
54
+ "style": "./styles/presets/momentum.css",
55
+ "default": "./styles/presets/momentum.css"
56
+ },
53
57
  "./package.json": {
54
58
  "default": "./package.json"
55
59
  },
@@ -184,6 +188,14 @@
184
188
  "./testing": {
185
189
  "types": "./types/mk-kit-ui-testing.d.ts",
186
190
  "default": "./fesm2022/mk-kit-ui-testing.mjs"
191
+ },
192
+ "./translate": {
193
+ "types": "./types/mk-kit-ui-translate.d.ts",
194
+ "default": "./fesm2022/mk-kit-ui-translate.mjs"
195
+ },
196
+ "./translate/server": {
197
+ "types": "./types/mk-kit-ui-translate-server.d.ts",
198
+ "default": "./fesm2022/mk-kit-ui-translate-server.mjs"
187
199
  }
188
200
  },
189
201
  "module": "fesm2022/mk-kit-ui.mjs",