@kopynator/angular 1.0.8 → 1.0.10
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
CHANGED
|
@@ -57,7 +57,27 @@ export const appConfig: ApplicationConfig = {
|
|
|
57
57
|
* **Best of Both Worlds**. First loads your local JSON files (instant render), then fetches updates from the Cloud in the background.
|
|
58
58
|
* Merges both sources, giving priority to the Cloud for any new or updated keys.
|
|
59
59
|
|
|
60
|
-
### 2.
|
|
60
|
+
### 2. Uso en plantillas (como ngx-translate)
|
|
61
|
+
|
|
62
|
+
Igual que **ngx-translate**: solo configuras el provider y usas el pipe o la directiva. **No hace falta ningún wrapper** (ni `<kopy-ready>` ni lógica extra en el componente raíz).
|
|
63
|
+
|
|
64
|
+
- **`provideKopynator`** usa `APP_INITIALIZER`: las traducciones se cargan **antes** de que arranque la app, así que la primera vista ya tiene las traducciones listas.
|
|
65
|
+
- El **pipe** y la **directiva** devuelven cadena vacía mientras no estén listas (nunca muestran la clave en crudo).
|
|
66
|
+
|
|
67
|
+
Tu `app.html` puede ser solo:
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<router-outlet></router-outlet>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
O con header/selector:
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<header><kopy-selector></kopy-selector></header>
|
|
77
|
+
<main><router-outlet></router-outlet></main>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 3. In Templates
|
|
61
81
|
```html
|
|
62
82
|
<!-- Using Pipe -->
|
|
63
83
|
<h1>{{ 'welcome_title' | kopy }}</h1>
|
|
@@ -65,6 +85,19 @@ export const appConfig: ApplicationConfig = {
|
|
|
65
85
|
<!-- Using Directive -->
|
|
66
86
|
<p [kopy]="'description'" [kopyParams]="{ name: 'Carlos' }"></p>
|
|
67
87
|
|
|
88
|
+
<!-- Language selector -->
|
|
89
|
+
<kopy-selector></kopy-selector>
|
|
90
|
+
|
|
68
91
|
<!-- Using Service -->
|
|
69
92
|
<button (click)="kopyService.setLocale('es')">Español</button>
|
|
70
93
|
```
|
|
94
|
+
|
|
95
|
+
### (Opcional) Componente \<kopy-ready\>
|
|
96
|
+
|
|
97
|
+
Solo si en tu entorno (p. ej. hidratación/SSR) ves un breve parpadeo de claves, puedes envolver el contenido en `<kopy-ready>`. En la mayoría de proyectos **no es necesario**; el `APP_INITIALIZER` ya evita el parpadeo.
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<kopy-ready>
|
|
101
|
+
<router-outlet></router-outlet>
|
|
102
|
+
</kopy-ready>
|
|
103
|
+
```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, signal, Inject, Injectable, Pipe, effect, Input, Directive, inject, Component, provideAppInitializer } from '@angular/core';
|
|
2
|
+
import { InjectionToken, signal, Inject, Injectable, Pipe, effect, Input, Directive, inject, Component, input, provideAppInitializer } from '@angular/core';
|
|
3
3
|
import { Kopynator } from '@kopynator/core';
|
|
4
4
|
import * as i1 from '@angular/common';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
@@ -67,7 +67,7 @@ class KopyPipe {
|
|
|
67
67
|
const ready = this.kopyService.isReady();
|
|
68
68
|
const locale = this.kopyService.currentLocale();
|
|
69
69
|
if (!ready)
|
|
70
|
-
return
|
|
70
|
+
return '';
|
|
71
71
|
return this.kopyService.translate(key, params);
|
|
72
72
|
}
|
|
73
73
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: KopyPipe, deps: [{ token: KopyService }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
@@ -103,6 +103,10 @@ class KopyDirective {
|
|
|
103
103
|
render() {
|
|
104
104
|
if (!this.key)
|
|
105
105
|
return;
|
|
106
|
+
if (!this.kopyService.isReady()) {
|
|
107
|
+
this.el.nativeElement.textContent = '';
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
106
110
|
this.el.nativeElement.textContent = this.kopyService.translate(this.key, this.kopyParams);
|
|
107
111
|
}
|
|
108
112
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: KopyDirective, deps: [{ token: i0.ElementRef }, { token: KopyService }], target: i0.ɵɵFactoryTarget.Directive });
|
|
@@ -215,8 +219,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
215
219
|
`, styles: [".kopy-selector-container{position:relative;display:inline-block;font-family:inherit}.kopy-selected-btn{display:flex;align-items:center;gap:6px;padding:4px 10px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:99px;color:#fff;cursor:pointer;transition:all .2s;font-size:11px;font-weight:700;min-width:70px;justify-content:center}.kopy-selected-btn:hover{background:#ffffff1a;border-color:#fff3}.chevron{width:10px;height:10px;opacity:.5;transition:transform .2s}.chevron.rotate{transform:rotate(180deg)}.kopy-dropdown{position:absolute;top:100%;right:0;margin-top:8px;background:#1e293b;border:1px solid rgba(255,255,255,.1);border-radius:12px;box-shadow:0 10px 25px -5px #00000080;overflow:hidden;min-width:140px;z-index:100;animation:slideIn .2s ease-out}.kopy-dropdown-item{width:100%;display:flex;align-items:center;gap:12px;padding:10px 16px;background:transparent;border:none;color:#94a3b8;cursor:pointer;text-align:left;transition:all .2s;font-size:14px}.kopy-dropdown-item:hover{background:#ffffff0d;color:#fff}.kopy-dropdown-item.active{color:#38bdf8;background:#38bdf80d}.label{flex:1}.flag{font-size:16px}@keyframes slideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
216
220
|
}] });
|
|
217
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Envuelve el contenido y solo lo muestra cuando las traducciones están cargadas (isReady).
|
|
224
|
+
* Evita el parpadeo de claves (FOUT) sin tener que usar señales ni afterNextRender en la app.
|
|
225
|
+
*
|
|
226
|
+
* Uso en app.html:
|
|
227
|
+
* <kopy-ready>
|
|
228
|
+
* <router-outlet></router-outlet>
|
|
229
|
+
* </kopy-ready>
|
|
230
|
+
*
|
|
231
|
+
* Opcional: showLoader=false para no mostrar spinner (solo espacio vacío hasta que cargue).
|
|
232
|
+
*/
|
|
233
|
+
class KopyReadyComponent {
|
|
234
|
+
kopyService = inject(KopyService);
|
|
235
|
+
/** Si true (por defecto), muestra un spinner mientras cargan las traducciones. */
|
|
236
|
+
showLoader = input(true, ...(ngDevMode ? [{ debugName: "showLoader" }] : []));
|
|
237
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: KopyReadyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
238
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: KopyReadyComponent, isStandalone: true, selector: "kopy-ready", inputs: { showLoader: { classPropertyName: "showLoader", publicName: "showLoader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
239
|
+
@if (kopyService.isReady()) {
|
|
240
|
+
<ng-content></ng-content>
|
|
241
|
+
} @else if (showLoader()) {
|
|
242
|
+
<div class="kopy-ready-loading" aria-busy="true" aria-label="Cargando traducciones">
|
|
243
|
+
<span class="kopy-ready-spinner" aria-hidden="true"></span>
|
|
244
|
+
</div>
|
|
245
|
+
}
|
|
246
|
+
`, isInline: true, styles: [".kopy-ready-loading{display:flex;align-items:center;justify-content:center;min-height:60vh}.kopy-ready-spinner{display:inline-block;width:2rem;height:2rem;border:2px solid rgba(6,182,212,.3);border-top-color:#06b6d4;border-radius:50%;animation:kopy-spin .7s linear infinite}@keyframes kopy-spin{to{transform:rotate(360deg)}}\n"] });
|
|
247
|
+
}
|
|
248
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: KopyReadyComponent, decorators: [{
|
|
249
|
+
type: Component,
|
|
250
|
+
args: [{ selector: 'kopy-ready', standalone: true, template: `
|
|
251
|
+
@if (kopyService.isReady()) {
|
|
252
|
+
<ng-content></ng-content>
|
|
253
|
+
} @else if (showLoader()) {
|
|
254
|
+
<div class="kopy-ready-loading" aria-busy="true" aria-label="Cargando traducciones">
|
|
255
|
+
<span class="kopy-ready-spinner" aria-hidden="true"></span>
|
|
256
|
+
</div>
|
|
257
|
+
}
|
|
258
|
+
`, styles: [".kopy-ready-loading{display:flex;align-items:center;justify-content:center;min-height:60vh}.kopy-ready-spinner{display:inline-block;width:2rem;height:2rem;border:2px solid rgba(6,182,212,.3);border-top-color:#06b6d4;border-radius:50%;animation:kopy-spin .7s linear infinite}@keyframes kopy-spin{to{transform:rotate(360deg)}}\n"] }]
|
|
259
|
+
}], propDecorators: { showLoader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLoader", required: false }] }] } });
|
|
260
|
+
|
|
218
261
|
/**
|
|
219
262
|
* Provides the Kopynator SDK configuration to the application.
|
|
263
|
+
* Like ngx-translate: translations are loaded in APP_INITIALIZER before the app
|
|
264
|
+
* bootstraps, so no wrapper component is needed and the pipe never shows raw keys.
|
|
220
265
|
*/
|
|
221
266
|
function provideKopynator(config) {
|
|
222
267
|
return [
|
|
@@ -236,5 +281,5 @@ function provideKopynator(config) {
|
|
|
236
281
|
* Generated bundle index. Do not edit.
|
|
237
282
|
*/
|
|
238
283
|
|
|
239
|
-
export { KOPY_CONFIG, KopyDirective, KopyPipe, KopySelectorComponent, KopyService, provideKopynator };
|
|
284
|
+
export { KOPY_CONFIG, KopyDirective, KopyPipe, KopyReadyComponent, KopySelectorComponent, KopyService, provideKopynator };
|
|
240
285
|
//# sourceMappingURL=kopynator-angular.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kopynator-angular.mjs","sources":["../../../../packages/angular/src/lib/kopy.service.ts","../../../../packages/angular/src/lib/kopy.pipe.ts","../../../../packages/angular/src/lib/kopy.directive.ts","../../../../packages/angular/src/lib/kopy.selector.component.ts","../../../../packages/angular/src/public-api.ts","../../../../packages/angular/src/kopynator-angular.ts"],"sourcesContent":["import { Injectable, Inject, InjectionToken, signal, NgZone } from '@angular/core';\nimport { Kopynator, KopyConfig } from '@kopynator/core';\n\nexport const KOPY_CONFIG = new InjectionToken<KopyConfig>('KOPY_CONFIG');\n\n@Injectable({\n providedIn: 'root'\n})\nexport class KopyService {\n private kopy: Kopynator;\n \n // Signals for reactivity\n public isReady = signal(false);\n public availableLanguages = signal<string[]>([]);\n public currentLocale = signal<string>('en');\n\n constructor(\n @Inject(KOPY_CONFIG) private config: KopyConfig,\n private zone: NgZone\n ) {\n const savedLocale = typeof localStorage !== 'undefined' ? localStorage.getItem('kopy_locale') : null;\n const initialLocale = savedLocale || config.defaultLocale || 'en';\n \n // Initialize core with the restored or default locale\n this.kopy = new Kopynator({ ...config, defaultLocale: initialLocale });\n this.currentLocale.set(initialLocale);\n }\n\n public async init(): Promise<void> {\n await this.kopy.init();\n \n this.zone.run(() => {\n this.availableLanguages.set(this.kopy.getLanguages());\n this.isReady.set(true);\n });\n }\n\n async setLocale(locale: string) {\n await this.kopy.setLocale(locale);\n \n if (typeof localStorage !== 'undefined') {\n localStorage.setItem('kopy_locale', locale);\n }\n\n this.zone.run(() => {\n this.currentLocale.set(locale);\n });\n }\n\n translate(key: string, params: Record<string, any> = {}): string {\n return this.kopy.translate(key, params);\n }\n\n getKopynator(): Kopynator {\n return this.kopy;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { KopyService } from './kopy.service';\n\n@Pipe({\n name: 'kopy',\n pure: false, // Must be false to react to signal changes inside transform\n standalone: true\n})\nexport class KopyPipe implements PipeTransform {\n constructor(\n private kopyService: KopyService\n ) {}\n\n transform(key: string, params: Record<string, any> = {}): string {\n // Establishing reactive dependencies on signals\n const ready = this.kopyService.isReady();\n const locale = this.kopyService.currentLocale();\n \n if (!ready) return key;\n\n return this.kopyService.translate(key, params);\n }\n}\n","import { Directive, ElementRef, Input, OnChanges, SimpleChanges, effect } from '@angular/core';\nimport { KopyService } from './kopy.service';\n\n@Directive({\n selector: '[kopy]',\n standalone: true\n})\nexport class KopyDirective implements OnChanges {\n @Input('kopy') key!: string;\n @Input() kopyParams: Record<string, any> = {};\n\n constructor(\n private el: ElementRef,\n private kopyService: KopyService\n ) {\n // React to signal changes in KopyService\n effect(() => {\n this.kopyService.currentLocale();\n this.kopyService.isReady();\n this.render();\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n this.render();\n }\n\n private render() {\n if (!this.key) return;\n this.el.nativeElement.textContent = this.kopyService.translate(this.key, this.kopyParams);\n }\n}\n","import { Component, inject, signal } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { KopyService } from './kopy.service';\n\n@Component({\n selector: 'kopy-selector',\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"kopy-selector-container\" [class.open]=\"isOpen()\">\n <button class=\"kopy-selected-btn\" (click)=\"toggleDropdown()\">\n <span class=\"flag\">{{ getFlag(currentLocale()) }}</span>\n <span class=\"label uppercase\">{{ currentLocale() }}</span>\n <svg class=\"chevron\" [class.rotate]=\"isOpen()\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n\n <div class=\"kopy-dropdown\" *ngIf=\"isOpen()\">\n <button \n *ngFor=\"let lang of languages()\" \n class=\"kopy-dropdown-item\"\n [class.active]=\"lang === currentLocale()\"\n (click)=\"selectLanguage(lang)\"\n >\n <span class=\"flag\">{{ getFlag(lang) }}</span>\n <span class=\"label\">{{ getNativeName(lang) }}</span>\n </button>\n </div>\n </div>\n `,\n styles: [`\n .kopy-selector-container {\n position: relative;\n display: inline-block;\n font-family: inherit;\n }\n .kopy-selected-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 99px;\n color: white;\n cursor: pointer;\n transition: all 0.2s;\n font-size: 11px;\n font-weight: 700;\n min-width: 70px;\n justify-content: center;\n }\n .kopy-selected-btn:hover {\n background: rgba(255, 255, 255, 0.1);\n border-color: rgba(255, 255, 255, 0.2);\n }\n .chevron {\n width: 10px;\n height: 10px;\n opacity: 0.5;\n transition: transform 0.2s;\n }\n .chevron.rotate {\n transform: rotate(180deg);\n }\n .kopy-dropdown {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: #1e293b;\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 12px;\n box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5);\n overflow: hidden;\n min-width: 140px;\n z-index: 100;\n animation: slideIn 0.2s ease-out;\n }\n .kopy-dropdown-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 16px;\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n text-align: left;\n transition: all 0.2s;\n font-size: 14px;\n }\n .kopy-dropdown-item:hover {\n background: rgba(255, 255, 255, 0.05);\n color: white;\n }\n .kopy-dropdown-item.active {\n color: #38bdf8;\n background: rgba(56, 189, 248, 0.05);\n }\n .label {\n flex: 1;\n }\n .flag {\n font-size: 16px;\n }\n @keyframes slideIn {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `]\n})\nexport class KopySelectorComponent {\n private kopyService = inject(KopyService);\n \n public isOpen = signal(false);\n public languages = this.kopyService.availableLanguages;\n public currentLocale = this.kopyService.currentLocale;\n\n private flagMap: Record<string, string> = {\n 'en': '🇺🇸',\n 'es': '🇪🇸',\n 'fr': '🇫🇷',\n 'de': '🇩🇪',\n 'it': '🇮🇹',\n 'pt': '🇵🇹',\n 'ja': '🇯🇵',\n 'zh': '🇨🇳',\n 'ru': '🇷🇺'\n };\n\n private nameMap: Record<string, string> = {\n 'en': 'English',\n 'es': 'Español',\n 'fr': 'Français',\n 'de': 'Deutsch',\n 'it': 'Italiano',\n 'pt': 'Português',\n 'ja': '日本語',\n 'zh': '中文',\n 'ru': 'Русский',\n 'en-us': 'English (US)'\n };\n\n toggleDropdown() {\n this.isOpen.set(!this.isOpen());\n }\n\n selectLanguage(lang: string) {\n this.kopyService.setLocale(lang);\n this.isOpen.set(false);\n }\n\n getFlag(lang: string): string {\n const code = lang.split('-')[0].toLowerCase();\n return this.flagMap[code] || '🌐';\n }\n\n getNativeName(lang: string): string {\n return this.nameMap[lang.toLowerCase()] || lang.toUpperCase();\n }\n}\n","import { Provider, provideAppInitializer, inject, EnvironmentProviders } from '@angular/core';\nimport { KopyConfig } from '@kopynator/core';\nimport { KOPY_CONFIG, KopyService } from './lib/kopy.service';\n\nexport * from './lib/kopy.service';\nexport * from './lib/kopy.pipe';\nexport * from './lib/kopy.directive';\nexport * from './lib/kopy.selector.component';\n\n/**\n * Provides the Kopynator SDK configuration to the application.\n */\nexport function provideKopynator(config: KopyConfig): (Provider | EnvironmentProviders)[] {\n return [\n {\n provide: KOPY_CONFIG,\n useValue: config\n },\n KopyService,\n provideAppInitializer(() => {\n const kopyService = inject(KopyService);\n return kopyService.init();\n })\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.KopyService"],"mappings":";;;;;;MAGa,WAAW,GAAG,IAAI,cAAc,CAAa,aAAa;MAK1D,WAAW,CAAA;AASS,IAAA,MAAA;AACrB,IAAA,IAAA;AATF,IAAA,IAAI;;AAGL,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,mDAAC;AACvB,IAAA,kBAAkB,GAAG,MAAM,CAAW,EAAE,8DAAC;AACzC,IAAA,aAAa,GAAG,MAAM,CAAS,IAAI,yDAAC;IAE3C,WAAA,CAC+B,MAAkB,EACvC,IAAY,EAAA;QADS,IAAA,CAAA,MAAM,GAAN,MAAM;QAC3B,IAAA,CAAA,IAAI,GAAJ,IAAI;AAEZ,QAAA,MAAM,WAAW,GAAG,OAAO,YAAY,KAAK,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;QACpG,MAAM,aAAa,GAAG,WAAW,IAAI,MAAM,CAAC,aAAa,IAAI,IAAI;;AAGjE,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AACtE,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC;IACvC;AAEO,IAAA,MAAM,IAAI,GAAA;AACf,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;AAEtB,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAK;AACjB,YAAA,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;AACrD,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,QAAA,CAAC,CAAC;IACJ;IAEA,MAAM,SAAS,CAAC,MAAc,EAAA;QAC5B,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;AAEjC,QAAA,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;AACvC,YAAA,YAAY,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC;QAC7C;AAEA,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAK;AACjB,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;AAChC,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,SAAS,CAAC,GAAW,EAAE,MAAA,GAA8B,EAAE,EAAA;QACrD,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC;IACzC;IAEA,YAAY,GAAA;QACV,OAAO,IAAI,CAAC,IAAI;IAClB;AA/CW,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,kBASZ,WAAW,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,MAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AATV,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cAFV,MAAM,EAAA,CAAA;;2FAEP,WAAW,EAAA,UAAA,EAAA,CAAA;kBAHvB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;0BAUI,MAAM;2BAAC,WAAW;;;MCTV,QAAQ,CAAA;AAET,IAAA,WAAA;AADV,IAAA,WAAA,CACU,WAAwB,EAAA;QAAxB,IAAA,CAAA,WAAW,GAAX,WAAW;IAClB;AAEH,IAAA,SAAS,CAAC,GAAW,EAAE,MAAA,GAA8B,EAAE,EAAA;;QAErD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE;AAE/C,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,GAAG;QAEtB,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC;IAChD;uGAbW,QAAQ,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,WAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA;qGAAR,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,KAAA,EAAA,CAAA;;2FAAR,QAAQ,EAAA,UAAA,EAAA,CAAA;kBALpB,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,KAAK;AACX,oBAAA,UAAU,EAAE;AACb,iBAAA;;;MCAY,aAAa,CAAA;AAKd,IAAA,EAAA;AACA,IAAA,WAAA;AALK,IAAA,GAAG;IACT,UAAU,GAAwB,EAAE;IAE7C,WAAA,CACU,EAAc,EACd,WAAwB,EAAA;QADxB,IAAA,CAAA,EAAE,GAAF,EAAE;QACF,IAAA,CAAA,WAAW,GAAX,WAAW;;QAGnB,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE;AAChC,YAAA,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;YAC1B,IAAI,CAAC,MAAM,EAAE;AACf,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,WAAW,CAAC,OAAsB,EAAA;QAChC,IAAI,CAAC,MAAM,EAAE;IACf;IAEQ,MAAM,GAAA;QACZ,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE;QACf,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC;IAC3F;uGAvBW,aAAa,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAAA,WAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,CAAA,MAAA,EAAA,KAAA,CAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBAJzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,QAAQ;AAClB,oBAAA,UAAU,EAAE;AACb,iBAAA;;sBAEE,KAAK;uBAAC,MAAM;;sBACZ;;;MCyGU,qBAAqB,CAAA;AACxB,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AAElC,IAAA,MAAM,GAAG,MAAM,CAAC,KAAK,kDAAC;AACtB,IAAA,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB;AAC/C,IAAA,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa;AAE7C,IAAA,OAAO,GAA2B;AACxC,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE;KACP;AAEO,IAAA,OAAO,GAA2B;AACxC,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,IAAI,EAAE,KAAK;AACX,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,OAAO,EAAE;KACV;IAED,cAAc,GAAA;QACZ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IACjC;AAEA,IAAA,cAAc,CAAC,IAAY,EAAA;AACzB,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC;AAChC,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;IACxB;AAEA,IAAA,OAAO,CAAC,IAAY,EAAA;AAClB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;QAC7C,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI;IACnC;AAEA,IAAA,aAAa,CAAC,IAAY,EAAA;AACxB,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE;IAC/D;uGAhDW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA1GtB;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,ytCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAvBS,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,cAAA,EAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA2GX,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBA9GjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,cACb,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,QAAA,EACb;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,ytCAAA,CAAA,EAAA;;;ACrBH;;AAEG;AACG,SAAU,gBAAgB,CAAC,MAAkB,EAAA;IACjD,OAAO;AACL,QAAA;AACE,YAAA,OAAO,EAAE,WAAW;AACpB,YAAA,QAAQ,EAAE;AACX,SAAA;QACD,WAAW;QACX,qBAAqB,CAAC,MAAK;AACvB,YAAA,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACvC,YAAA,OAAO,WAAW,CAAC,IAAI,EAAE;AAC7B,QAAA,CAAC;KACF;AACH;;ACxBA;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"kopynator-angular.mjs","sources":["../../../../packages/angular/src/lib/kopy.service.ts","../../../../packages/angular/src/lib/kopy.pipe.ts","../../../../packages/angular/src/lib/kopy.directive.ts","../../../../packages/angular/src/lib/kopy.selector.component.ts","../../../../packages/angular/src/lib/kopy-ready.component.ts","../../../../packages/angular/src/public-api.ts","../../../../packages/angular/src/kopynator-angular.ts"],"sourcesContent":["import { Injectable, Inject, InjectionToken, signal, NgZone } from '@angular/core';\nimport { Kopynator, KopyConfig } from '@kopynator/core';\n\nexport const KOPY_CONFIG = new InjectionToken<KopyConfig>('KOPY_CONFIG');\n\n@Injectable({\n providedIn: 'root'\n})\nexport class KopyService {\n private kopy: Kopynator;\n \n // Signals for reactivity\n public isReady = signal(false);\n public availableLanguages = signal<string[]>([]);\n public currentLocale = signal<string>('en');\n\n constructor(\n @Inject(KOPY_CONFIG) private config: KopyConfig,\n private zone: NgZone\n ) {\n const savedLocale = typeof localStorage !== 'undefined' ? localStorage.getItem('kopy_locale') : null;\n const initialLocale = savedLocale || config.defaultLocale || 'en';\n \n // Initialize core with the restored or default locale\n this.kopy = new Kopynator({ ...config, defaultLocale: initialLocale });\n this.currentLocale.set(initialLocale);\n }\n\n public async init(): Promise<void> {\n await this.kopy.init();\n \n this.zone.run(() => {\n this.availableLanguages.set(this.kopy.getLanguages());\n this.isReady.set(true);\n });\n }\n\n async setLocale(locale: string) {\n await this.kopy.setLocale(locale);\n \n if (typeof localStorage !== 'undefined') {\n localStorage.setItem('kopy_locale', locale);\n }\n\n this.zone.run(() => {\n this.currentLocale.set(locale);\n });\n }\n\n translate(key: string, params: Record<string, any> = {}): string {\n return this.kopy.translate(key, params);\n }\n\n getKopynator(): Kopynator {\n return this.kopy;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { KopyService } from './kopy.service';\n\n@Pipe({\n name: 'kopy',\n pure: false, // Must be false to react to signal changes inside transform\n standalone: true\n})\nexport class KopyPipe implements PipeTransform {\n constructor(\n private kopyService: KopyService\n ) {}\n\n transform(key: string, params: Record<string, any> = {}): string {\n // Establishing reactive dependencies on signals\n const ready = this.kopyService.isReady();\n const locale = this.kopyService.currentLocale();\n if (!ready) return '';\n\n return this.kopyService.translate(key, params);\n }\n}\n","import { Directive, ElementRef, Input, OnChanges, SimpleChanges, effect } from '@angular/core';\nimport { KopyService } from './kopy.service';\n\n@Directive({\n selector: '[kopy]',\n standalone: true\n})\nexport class KopyDirective implements OnChanges {\n @Input('kopy') key!: string;\n @Input() kopyParams: Record<string, any> = {};\n\n constructor(\n private el: ElementRef,\n private kopyService: KopyService\n ) {\n // React to signal changes in KopyService\n effect(() => {\n this.kopyService.currentLocale();\n this.kopyService.isReady();\n this.render();\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n this.render();\n }\n\n private render() {\n if (!this.key) return;\n if (!this.kopyService.isReady()) {\n this.el.nativeElement.textContent = '';\n return;\n }\n this.el.nativeElement.textContent = this.kopyService.translate(this.key, this.kopyParams);\n }\n}\n","import { Component, inject, signal } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { KopyService } from './kopy.service';\n\n@Component({\n selector: 'kopy-selector',\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"kopy-selector-container\" [class.open]=\"isOpen()\">\n <button class=\"kopy-selected-btn\" (click)=\"toggleDropdown()\">\n <span class=\"flag\">{{ getFlag(currentLocale()) }}</span>\n <span class=\"label uppercase\">{{ currentLocale() }}</span>\n <svg class=\"chevron\" [class.rotate]=\"isOpen()\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n\n <div class=\"kopy-dropdown\" *ngIf=\"isOpen()\">\n <button \n *ngFor=\"let lang of languages()\" \n class=\"kopy-dropdown-item\"\n [class.active]=\"lang === currentLocale()\"\n (click)=\"selectLanguage(lang)\"\n >\n <span class=\"flag\">{{ getFlag(lang) }}</span>\n <span class=\"label\">{{ getNativeName(lang) }}</span>\n </button>\n </div>\n </div>\n `,\n styles: [`\n .kopy-selector-container {\n position: relative;\n display: inline-block;\n font-family: inherit;\n }\n .kopy-selected-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 99px;\n color: white;\n cursor: pointer;\n transition: all 0.2s;\n font-size: 11px;\n font-weight: 700;\n min-width: 70px;\n justify-content: center;\n }\n .kopy-selected-btn:hover {\n background: rgba(255, 255, 255, 0.1);\n border-color: rgba(255, 255, 255, 0.2);\n }\n .chevron {\n width: 10px;\n height: 10px;\n opacity: 0.5;\n transition: transform 0.2s;\n }\n .chevron.rotate {\n transform: rotate(180deg);\n }\n .kopy-dropdown {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: #1e293b;\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 12px;\n box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5);\n overflow: hidden;\n min-width: 140px;\n z-index: 100;\n animation: slideIn 0.2s ease-out;\n }\n .kopy-dropdown-item {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 16px;\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n text-align: left;\n transition: all 0.2s;\n font-size: 14px;\n }\n .kopy-dropdown-item:hover {\n background: rgba(255, 255, 255, 0.05);\n color: white;\n }\n .kopy-dropdown-item.active {\n color: #38bdf8;\n background: rgba(56, 189, 248, 0.05);\n }\n .label {\n flex: 1;\n }\n .flag {\n font-size: 16px;\n }\n @keyframes slideIn {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `]\n})\nexport class KopySelectorComponent {\n private kopyService = inject(KopyService);\n \n public isOpen = signal(false);\n public languages = this.kopyService.availableLanguages;\n public currentLocale = this.kopyService.currentLocale;\n\n private flagMap: Record<string, string> = {\n 'en': '🇺🇸',\n 'es': '🇪🇸',\n 'fr': '🇫🇷',\n 'de': '🇩🇪',\n 'it': '🇮🇹',\n 'pt': '🇵🇹',\n 'ja': '🇯🇵',\n 'zh': '🇨🇳',\n 'ru': '🇷🇺'\n };\n\n private nameMap: Record<string, string> = {\n 'en': 'English',\n 'es': 'Español',\n 'fr': 'Français',\n 'de': 'Deutsch',\n 'it': 'Italiano',\n 'pt': 'Português',\n 'ja': '日本語',\n 'zh': '中文',\n 'ru': 'Русский',\n 'en-us': 'English (US)'\n };\n\n toggleDropdown() {\n this.isOpen.set(!this.isOpen());\n }\n\n selectLanguage(lang: string) {\n this.kopyService.setLocale(lang);\n this.isOpen.set(false);\n }\n\n getFlag(lang: string): string {\n const code = lang.split('-')[0].toLowerCase();\n return this.flagMap[code] || '🌐';\n }\n\n getNativeName(lang: string): string {\n return this.nameMap[lang.toLowerCase()] || lang.toUpperCase();\n }\n}\n","import { Component, inject, input } from '@angular/core';\nimport { KopyService } from './kopy.service';\n\n/**\n * Envuelve el contenido y solo lo muestra cuando las traducciones están cargadas (isReady).\n * Evita el parpadeo de claves (FOUT) sin tener que usar señales ni afterNextRender en la app.\n *\n * Uso en app.html:\n * <kopy-ready>\n * <router-outlet></router-outlet>\n * </kopy-ready>\n *\n * Opcional: showLoader=false para no mostrar spinner (solo espacio vacío hasta que cargue).\n */\n@Component({\n selector: 'kopy-ready',\n standalone: true,\n template: `\n @if (kopyService.isReady()) {\n <ng-content></ng-content>\n } @else if (showLoader()) {\n <div class=\"kopy-ready-loading\" aria-busy=\"true\" aria-label=\"Cargando traducciones\">\n <span class=\"kopy-ready-spinner\" aria-hidden=\"true\"></span>\n </div>\n }\n `,\n styles: [`\n .kopy-ready-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 60vh;\n }\n .kopy-ready-spinner {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n border: 2px solid rgba(6, 182, 212, 0.3);\n border-top-color: rgb(6, 182, 212);\n border-radius: 50%;\n animation: kopy-spin 0.7s linear infinite;\n }\n @keyframes kopy-spin {\n to { transform: rotate(360deg); }\n }\n `]\n})\nexport class KopyReadyComponent {\n readonly kopyService = inject(KopyService);\n /** Si true (por defecto), muestra un spinner mientras cargan las traducciones. */\n readonly showLoader = input<boolean>(true);\n}\n","import { Provider, provideAppInitializer, inject, EnvironmentProviders } from '@angular/core';\nimport { KopyConfig } from '@kopynator/core';\nimport { KOPY_CONFIG, KopyService } from './lib/kopy.service';\n\nexport * from './lib/kopy.service';\nexport * from './lib/kopy.pipe';\nexport * from './lib/kopy.directive';\nexport * from './lib/kopy.selector.component';\nexport * from './lib/kopy-ready.component';\n\n/**\n * Provides the Kopynator SDK configuration to the application.\n * Like ngx-translate: translations are loaded in APP_INITIALIZER before the app\n * bootstraps, so no wrapper component is needed and the pipe never shows raw keys.\n */\nexport function provideKopynator(config: KopyConfig): (Provider | EnvironmentProviders)[] {\n return [\n {\n provide: KOPY_CONFIG,\n useValue: config\n },\n KopyService,\n provideAppInitializer(() => {\n const kopyService = inject(KopyService);\n return kopyService.init();\n })\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.KopyService"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -54,9 +54,30 @@ declare class KopySelectorComponent {
|
|
|
54
54
|
static ɵcmp: i0.ɵɵComponentDeclaration<KopySelectorComponent, "kopy-selector", never, {}, {}, never, never, true, never>;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Envuelve el contenido y solo lo muestra cuando las traducciones están cargadas (isReady).
|
|
59
|
+
* Evita el parpadeo de claves (FOUT) sin tener que usar señales ni afterNextRender en la app.
|
|
60
|
+
*
|
|
61
|
+
* Uso en app.html:
|
|
62
|
+
* <kopy-ready>
|
|
63
|
+
* <router-outlet></router-outlet>
|
|
64
|
+
* </kopy-ready>
|
|
65
|
+
*
|
|
66
|
+
* Opcional: showLoader=false para no mostrar spinner (solo espacio vacío hasta que cargue).
|
|
67
|
+
*/
|
|
68
|
+
declare class KopyReadyComponent {
|
|
69
|
+
readonly kopyService: KopyService;
|
|
70
|
+
/** Si true (por defecto), muestra un spinner mientras cargan las traducciones. */
|
|
71
|
+
readonly showLoader: i0.InputSignal<boolean>;
|
|
72
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<KopyReadyComponent, never>;
|
|
73
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<KopyReadyComponent, "kopy-ready", never, { "showLoader": { "alias": "showLoader"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
74
|
+
}
|
|
75
|
+
|
|
57
76
|
/**
|
|
58
77
|
* Provides the Kopynator SDK configuration to the application.
|
|
78
|
+
* Like ngx-translate: translations are loaded in APP_INITIALIZER before the app
|
|
79
|
+
* bootstraps, so no wrapper component is needed and the pipe never shows raw keys.
|
|
59
80
|
*/
|
|
60
81
|
declare function provideKopynator(config: KopyConfig): (Provider | EnvironmentProviders)[];
|
|
61
82
|
|
|
62
|
-
export { KOPY_CONFIG, KopyDirective, KopyPipe, KopySelectorComponent, KopyService, provideKopynator };
|
|
83
|
+
export { KOPY_CONFIG, KopyDirective, KopyPipe, KopyReadyComponent, KopySelectorComponent, KopyService, provideKopynator };
|