valtech-components 2.0.301 → 2.0.304

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.
Files changed (29) hide show
  1. package/esm2022/lib/components/atoms/button/button.component.mjs +103 -23
  2. package/esm2022/lib/components/types.mjs +1 -1
  3. package/esm2022/lib/services/lang-provider/content.mjs +1 -55
  4. package/esm2022/lib/services/lang-provider/lang-provider.service.mjs +5 -4
  5. package/esm2022/public-api.mjs +1 -11
  6. package/fesm2022/valtech-components.mjs +124 -2534
  7. package/fesm2022/valtech-components.mjs.map +1 -1
  8. package/lib/components/atoms/button/button.component.d.ts +33 -2
  9. package/lib/components/types.d.ts +19 -7
  10. package/package.json +1 -1
  11. package/public-api.d.ts +0 -9
  12. package/esm2022/lib/examples/comprehensive-link-test.component.mjs +0 -208
  13. package/esm2022/lib/examples/custom-content-demo.component.mjs +0 -291
  14. package/esm2022/lib/examples/display-demo.component.mjs +0 -518
  15. package/esm2022/lib/examples/display-simple-example.component.mjs +0 -202
  16. package/esm2022/lib/examples/link-processing-example.component.mjs +0 -233
  17. package/esm2022/lib/examples/multi-language-demo.component.mjs +0 -304
  18. package/esm2022/lib/examples/reactive-components-demo.component.mjs +0 -303
  19. package/esm2022/lib/examples/reactivity-test.component.mjs +0 -200
  20. package/esm2022/lib/examples/selector-examples.component.mjs +0 -234
  21. package/lib/examples/comprehensive-link-test.component.d.ts +0 -23
  22. package/lib/examples/custom-content-demo.component.d.ts +0 -26
  23. package/lib/examples/display-demo.component.d.ts +0 -62
  24. package/lib/examples/display-simple-example.component.d.ts +0 -23
  25. package/lib/examples/link-processing-example.component.d.ts +0 -26
  26. package/lib/examples/multi-language-demo.component.d.ts +0 -34
  27. package/lib/examples/reactive-components-demo.component.d.ts +0 -45
  28. package/lib/examples/reactivity-test.component.d.ts +0 -27
  29. package/lib/examples/selector-examples.component.d.ts +0 -21
@@ -5,7 +5,7 @@ import * as i1 from '@angular/common';
5
5
  import { CommonModule, NgStyle, AsyncPipe, NgFor, NgClass } from '@angular/common';
6
6
  import { addIcons } from 'ionicons';
7
7
  import { addOutline, addCircleOutline, alertOutline, alertCircleOutline, arrowBackOutline, arrowForwardOutline, arrowDownOutline, checkmarkCircleOutline, ellipsisHorizontalOutline, notificationsOutline, openOutline, closeOutline, chatbubblesOutline, shareOutline, heart, heartOutline, homeOutline, eyeOffOutline, eyeOutline, scanOutline, chevronDownOutline, chevronForwardOutline, checkmarkOutline, clipboardOutline, copyOutline, filterOutline, locationOutline, calendarOutline, businessOutline, logoTwitter, logoInstagram, logoLinkedin, logoYoutube, logoTiktok, logoFacebook, createOutline, trashOutline, playOutline, refreshOutline, documentTextOutline, lockClosedOutline, informationCircleOutline, logoNpm, chevronDown, language, globe, chevronBackOutline } from 'ionicons/icons';
8
- import { map, BehaviorSubject, distinctUntilChanged, Subscription, of, combineLatest } from 'rxjs';
8
+ import { map, BehaviorSubject, distinctUntilChanged, shareReplay, Subscription, of, combineLatest } from 'rxjs';
9
9
  import { Router, RouterLink } from '@angular/router';
10
10
  import { Browser } from '@capacitor/browser';
11
11
  import * as i1$1 from '@angular/platform-browser';
@@ -832,7 +832,8 @@ class LangService {
832
832
  * Use this to subscribe to language changes in components.
833
833
  */
834
834
  get currentLang$() {
835
- return this.selectedLang.asObservable().pipe(distinctUntilChanged());
835
+ return this.selectedLang.asObservable().pipe(distinctUntilChanged(), shareReplay(1) // Ensure new subscribers get the current value
836
+ );
836
837
  }
837
838
  /**
838
839
  * Get the current language synchronously.
@@ -911,7 +912,7 @@ class LangService {
911
912
  console.warn(`LangService: Content "${className}.${key}" not available in "${lang}".`, `Using "${result.actualLang}" instead. Available languages:`, this.availableLanguages);
912
913
  }
913
914
  return result.content || fallback || `[${className}.${key}]`;
914
- }), distinctUntilChanged((prev, curr) => prev === curr));
915
+ }), distinctUntilChanged());
915
916
  }
916
917
  /**
917
918
  * Get reactive content for multiple keys at once.
@@ -1338,15 +1339,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1338
1339
  *
1339
1340
  * A customizable button supporting icons, loading state, navigation, and reactive content.
1340
1341
  * Supports both static text and reactive content from the content service.
1342
+ * Follows the same content pattern as val-text for consistency.
1341
1343
  *
1342
- * @example
1343
- * // Static text
1344
- * <val-button [props]="{ text: 'Save', color: 'primary', icon: { name: 'save', slot: 'start' } }" (onClick)="handler()"></val-button>
1344
+ * @example Static text:
1345
+ * <val-button [props]="{
1346
+ * text: 'Save',
1347
+ * color: 'primary',
1348
+ * type: 'button',
1349
+ * state: 'ENABLED',
1350
+ * icon: { name: 'save', slot: 'start' }
1351
+ * }" (onClick)="handler()"></val-button>
1345
1352
  *
1346
- * // Reactive content
1347
- * <val-button [props]="{ textConfig: { key: 'save' }, color: 'primary', icon: { name: 'save', slot: 'start' } }" (onClick)="handler()"></val-button>
1353
+ * @example Reactive content:
1354
+ * <val-button [props]="{
1355
+ * contentKey: 'save',
1356
+ * contentClass: 'MyComponent',
1357
+ * contentFallback: 'Save',
1358
+ * color: 'primary',
1359
+ * type: 'button',
1360
+ * state: 'ENABLED',
1361
+ * icon: { name: 'save', slot: 'start' }
1362
+ * }" (onClick)="handler()"></val-button>
1363
+ *
1364
+ * @example Reactive content with interpolation:
1365
+ * <val-button [props]="{
1366
+ * contentKey: 'saveCount',
1367
+ * contentClass: 'MyComponent',
1368
+ * contentInterpolation: { count: 5 },
1369
+ * contentFallback: 'Save Items',
1370
+ * color: 'primary',
1371
+ * type: 'button',
1372
+ * state: 'ENABLED'
1373
+ * }" (onClick)="handler()"></val-button>
1348
1374
  *
1349
- * @input props: ButtonMetadata - Configuration for the button (text/textConfig, color, icon, state, etc.)
1375
+ * @input props: ButtonMetadata - Configuration for the button (text/content, color, icon, state, etc.)
1350
1376
  * @output onClick - Emits when the button is clicked
1351
1377
  */
1352
1378
  class ButtonComponent {
@@ -1362,29 +1388,46 @@ class ButtonComponent {
1362
1388
  this.onClick = new EventEmitter();
1363
1389
  }
1364
1390
  ngOnInit() {
1365
- this.initializeDisplayText();
1391
+ this.setupDisplayText();
1366
1392
  }
1367
1393
  ngOnDestroy() {
1368
1394
  this.subscriptions.unsubscribe();
1369
1395
  }
1370
- initializeDisplayText() {
1371
- // Static text takes precedence
1372
- if (this.props.text !== undefined) {
1396
+ /**
1397
+ * Set up the text content observable based on the props configuration.
1398
+ * Priority: static text > reactive content with interpolation > reactive content
1399
+ * This follows the same pattern as val-text component.
1400
+ */
1401
+ setupDisplayText() {
1402
+ if (this.props.text) {
1403
+ // Static text takes precedence
1373
1404
  this.displayText$ = of(this.props.text);
1374
- return;
1375
1405
  }
1376
- // Use reactive content if configured
1377
- if (this.props.textConfig) {
1378
- this.displayText$ = this.contentService.fromContent({
1379
- className: this.props.textConfig.className || '_global',
1380
- key: this.props.textConfig.key,
1381
- fallback: this.props.textConfig.fallback || this.props.textConfig.key,
1382
- interpolation: this.props.textConfig.interpolation,
1383
- });
1384
- return;
1406
+ else if (this.props.contentKey && this.props.contentClass) {
1407
+ // Reactive content from language service
1408
+ if (this.props.contentInterpolation) {
1409
+ // With interpolation
1410
+ this.displayText$ = this.contentService.fromContentWithInterpolation({
1411
+ className: this.props.contentClass,
1412
+ key: this.props.contentKey,
1413
+ fallback: this.props.contentFallback,
1414
+ interpolation: this.props.contentInterpolation,
1415
+ });
1416
+ }
1417
+ else {
1418
+ // Simple reactive content
1419
+ this.displayText$ = this.contentService.fromContent({
1420
+ className: this.props.contentClass,
1421
+ key: this.props.contentKey,
1422
+ fallback: this.props.contentFallback,
1423
+ });
1424
+ }
1425
+ }
1426
+ else {
1427
+ // Fallback to empty string if no valid content configuration
1428
+ console.warn('val-button: No valid content configuration provided. Use either "text" for static text or "contentKey" + "contentClass" for reactive content.');
1429
+ this.displayText$ = of(this.props.contentFallback || '');
1385
1430
  }
1386
- // No content configured - use empty string
1387
- this.displayText$ = of('');
1388
1431
  }
1389
1432
  clickHandler() {
1390
1433
  if (this.props.state === this.states.DISABLED) {
@@ -1448,6 +1491,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1448
1491
  }], onClick: [{
1449
1492
  type: Output
1450
1493
  }] } });
1494
+ /**
1495
+ * Helper function to create reactive button props from content configuration.
1496
+ * This provides a convenient way to create val-button props with reactive content.
1497
+ * Follows the same pattern as createTextProps for consistency.
1498
+ *
1499
+ * @param contentConfig - Content configuration
1500
+ * @param styleConfig - Optional style and behavior configuration
1501
+ * @returns ButtonMetadata with content properties set
1502
+ *
1503
+ * @example
1504
+ * ```typescript
1505
+ * // In component
1506
+ * saveButtonProps: ButtonMetadata = createButtonProps({
1507
+ * contentKey: 'save',
1508
+ * contentClass: 'MyComponent'
1509
+ * }, {
1510
+ * color: 'primary',
1511
+ * icon: { name: 'save', slot: 'start' }
1512
+ * });
1513
+ * ```
1514
+ */
1515
+ function createButtonProps(contentConfig, styleConfig = {}) {
1516
+ return {
1517
+ contentKey: contentConfig.contentKey,
1518
+ contentClass: contentConfig.contentClass,
1519
+ contentFallback: contentConfig.contentFallback,
1520
+ contentInterpolation: contentConfig.contentInterpolation,
1521
+ color: styleConfig.color || 'primary',
1522
+ type: styleConfig.type || 'button',
1523
+ state: styleConfig.state || ComponentStates.ENABLED,
1524
+ size: styleConfig.size,
1525
+ fill: styleConfig.fill,
1526
+ icon: styleConfig.icon,
1527
+ expand: styleConfig.expand,
1528
+ shape: styleConfig.shape,
1529
+ handler: styleConfig.handler,
1530
+ };
1531
+ }
1451
1532
 
1452
1533
  const Icon = (name, slot) => {
1453
1534
  return {
@@ -7196,2462 +7277,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7196
7277
  type: Output
7197
7278
  }] } });
7198
7279
 
7199
- /**
7200
- * ComprehensiveLinkTestComponent - Componente de prueba exhaustiva para el procesamiento de enlaces.
7201
- *
7202
- * Este componente demuestra todos los casos edge y escenarios complejos de procesamiento de enlaces,
7203
- * incluyendo puntuación, URLs complejas, y mezclas de formatos.
7204
- *
7205
- * @example Uso en template:
7206
- * ```html
7207
- * <val-comprehensive-link-test></val-comprehensive-link-test>
7208
- * ```
7209
- */
7210
- class ComprehensiveLinkTestComponent {
7211
- constructor() {
7212
- this.punctuationProps = {
7213
- content: 'Diferentes puntuaciones: https://angular.io, también https://github.com! ¿Conoces https://typescript.org? Final: https://rxjs.dev. Entre paréntesis (https://zone.js) y con comillas "https://ionic.io".',
7214
- size: 'medium',
7215
- color: 'dark',
7216
- bold: false,
7217
- processLinks: true,
7218
- linkConfig: {
7219
- openExternalInNewTab: true,
7220
- linkClass: 'test-punctuation',
7221
- externalLinkClass: 'test-external',
7222
- },
7223
- };
7224
- this.complexUrlProps = {
7225
- content: 'URLs complejas: https://api.github.com/repos/angular/angular/issues?state=open&sort=updated&per_page=50, búsqueda https://google.com/search?q=angular+ionic+components#results, y documentación https://angular.io/guide/getting-started#development-environment.',
7226
- size: 'medium',
7227
- color: 'dark',
7228
- bold: false,
7229
- processLinks: true,
7230
- linkConfig: {
7231
- openExternalInNewTab: true,
7232
- linkClass: 'test-complex',
7233
- externalLinkClass: 'test-external',
7234
- },
7235
- };
7236
- this.parenthesesProps = {
7237
- content: 'Paréntesis de contexto (ver https://docs.angular.io) vs URLs con paréntesis https://example.com/api/method(param) en el contenido. También funciona (https://ionic.io/docs).',
7238
- size: 'medium',
7239
- color: 'dark',
7240
- bold: false,
7241
- processLinks: true,
7242
- linkConfig: {
7243
- openExternalInNewTab: true,
7244
- linkClass: 'test-parentheses',
7245
- externalLinkClass: 'test-external',
7246
- },
7247
- };
7248
- this.mixedFormatsProps = {
7249
- content: 'Formatos mezclados: [Documentación oficial](https://angular.io/docs), enlace directo https://github.com/angular/angular, ruta interna /dashboard/settings, [guía de inicio](/getting-started), y API https://api.example.com/v1/users?active=true.',
7250
- size: 'medium',
7251
- color: 'dark',
7252
- bold: false,
7253
- processLinks: true,
7254
- linkConfig: {
7255
- openExternalInNewTab: true,
7256
- openInternalInNewTab: false,
7257
- processMarkdownLinks: true,
7258
- linkClass: 'test-mixed',
7259
- externalLinkClass: 'test-external',
7260
- internalLinkClass: 'test-internal',
7261
- },
7262
- };
7263
- this.edgeCasesProps = {
7264
- content: 'Casos extremos: "https://quoted-url.com", múltiple puntuación https://example.com?!!, URL al final de oración https://final-url.org. También consecutivos: https://first.com y https://second.com.',
7265
- size: 'medium',
7266
- color: 'dark',
7267
- bold: false,
7268
- processLinks: true,
7269
- linkConfig: {
7270
- openExternalInNewTab: true,
7271
- linkClass: 'test-edge',
7272
- externalLinkClass: 'test-external',
7273
- },
7274
- };
7275
- this.devUrlsProps = {
7276
- content: 'URLs de desarrollo: http://localhost:4200/dashboard, servidor local https://127.0.0.1:8080/api/status, desarrollo http://dev.example.com:3000/debug?verbose=true, y túnel https://abc123.ngrok.io/webhook.',
7277
- size: 'medium',
7278
- color: 'dark',
7279
- bold: false,
7280
- processLinks: true,
7281
- linkConfig: {
7282
- openExternalInNewTab: false, // Para desarrollo, puede ser útil no abrir en nueva pestaña
7283
- linkClass: 'test-dev',
7284
- externalLinkClass: 'test-dev-external',
7285
- },
7286
- };
7287
- }
7288
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComprehensiveLinkTestComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7289
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ComprehensiveLinkTestComponent, isStandalone: true, selector: "val-comprehensive-link-test", ngImport: i0, template: `
7290
- <div class="comprehensive-test">
7291
- <h2>Prueba Exhaustiva de Procesamiento de Enlaces</h2>
7292
-
7293
- <div class="test-section">
7294
- <h3>✅ Puntuación Final - SOLUCIONADO</h3>
7295
- <val-text [props]="punctuationProps"></val-text>
7296
- <p class="note">
7297
- <strong>Esperado:</strong> Los enlaces no incluyen puntuación final (.,;!?), pero la puntuación se preserva
7298
- como texto después del enlace.
7299
- </p>
7300
- </div>
7301
-
7302
- <div class="test-section">
7303
- <h3>✅ URLs Complejas con Parámetros - SOLUCIONADO</h3>
7304
- <val-text [props]="complexUrlProps"></val-text>
7305
- <p class="note">
7306
- <strong>Esperado:</strong> URLs con query params, fragmentos y rutas complejas se preservan completamente.
7307
- </p>
7308
- </div>
7309
-
7310
- <div class="test-section">
7311
- <h3>✅ Paréntesis Inteligentes - SOLUCIONADO</h3>
7312
- <val-text [props]="parenthesesProps"></val-text>
7313
- <p class="note">
7314
- <strong>Esperado:</strong> Paréntesis de contexto (texto) vs paréntesis de URL se manejan correctamente.
7315
- </p>
7316
- </div>
7317
-
7318
- <div class="test-section">
7319
- <h3>✅ Mezcla de Formatos - SOLUCIONADO</h3>
7320
- <val-text [props]="mixedFormatsProps"></val-text>
7321
- <p class="note">
7322
- <strong>Esperado:</strong> Enlaces Markdown, URLs directas y rutas internas coexisten sin conflictos.
7323
- </p>
7324
- </div>
7325
-
7326
- <div class="test-section">
7327
- <h3>✅ Casos Extremos - SOLUCIONADO</h3>
7328
- <val-text [props]="edgeCasesProps"></val-text>
7329
- <p class="note">
7330
- <strong>Esperado:</strong> Comillas, múltiple puntuación, y URLs al final de oraciones se procesan
7331
- correctamente.
7332
- </p>
7333
- </div>
7334
-
7335
- <div class="test-section">
7336
- <h3>✅ URLs de Desarrollo - SOLUCIONADO</h3>
7337
- <val-text [props]="devUrlsProps"></val-text>
7338
- <p class="note">
7339
- <strong>Esperado:</strong> URLs de localhost, puertos, y rutas de desarrollo se detectan correctamente.
7340
- </p>
7341
- </div>
7342
- </div>
7343
- `, isInline: true, styles: [".comprehensive-test{padding:20px;max-width:1000px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.test-section{margin-bottom:32px;padding:20px;border:2px solid var(--ion-color-success, #2dd36f);border-radius:12px;background:var(--ion-color-success-tint, #42d77d) 10}h2{color:var(--ion-color-primary, #3880ff);margin-bottom:24px;text-align:center}h3{color:var(--ion-color-success, #2dd36f);margin-bottom:16px;font-size:18px;display:flex;align-items:center;gap:8px}.note{margin-top:12px;padding:12px;background:var(--ion-color-light, #f4f5f8);border-radius:8px;font-size:14px;color:var(--ion-color-medium, #92949c);border-left:4px solid var(--ion-color-primary, #3880ff)}.note strong{color:var(--ion-color-dark, #222428)}\n"], dependencies: [{ kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }] }); }
7344
- }
7345
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComprehensiveLinkTestComponent, decorators: [{
7346
- type: Component,
7347
- args: [{ selector: 'val-comprehensive-link-test', standalone: true, imports: [TextComponent], template: `
7348
- <div class="comprehensive-test">
7349
- <h2>Prueba Exhaustiva de Procesamiento de Enlaces</h2>
7350
-
7351
- <div class="test-section">
7352
- <h3>✅ Puntuación Final - SOLUCIONADO</h3>
7353
- <val-text [props]="punctuationProps"></val-text>
7354
- <p class="note">
7355
- <strong>Esperado:</strong> Los enlaces no incluyen puntuación final (.,;!?), pero la puntuación se preserva
7356
- como texto después del enlace.
7357
- </p>
7358
- </div>
7359
-
7360
- <div class="test-section">
7361
- <h3>✅ URLs Complejas con Parámetros - SOLUCIONADO</h3>
7362
- <val-text [props]="complexUrlProps"></val-text>
7363
- <p class="note">
7364
- <strong>Esperado:</strong> URLs con query params, fragmentos y rutas complejas se preservan completamente.
7365
- </p>
7366
- </div>
7367
-
7368
- <div class="test-section">
7369
- <h3>✅ Paréntesis Inteligentes - SOLUCIONADO</h3>
7370
- <val-text [props]="parenthesesProps"></val-text>
7371
- <p class="note">
7372
- <strong>Esperado:</strong> Paréntesis de contexto (texto) vs paréntesis de URL se manejan correctamente.
7373
- </p>
7374
- </div>
7375
-
7376
- <div class="test-section">
7377
- <h3>✅ Mezcla de Formatos - SOLUCIONADO</h3>
7378
- <val-text [props]="mixedFormatsProps"></val-text>
7379
- <p class="note">
7380
- <strong>Esperado:</strong> Enlaces Markdown, URLs directas y rutas internas coexisten sin conflictos.
7381
- </p>
7382
- </div>
7383
-
7384
- <div class="test-section">
7385
- <h3>✅ Casos Extremos - SOLUCIONADO</h3>
7386
- <val-text [props]="edgeCasesProps"></val-text>
7387
- <p class="note">
7388
- <strong>Esperado:</strong> Comillas, múltiple puntuación, y URLs al final de oraciones se procesan
7389
- correctamente.
7390
- </p>
7391
- </div>
7392
-
7393
- <div class="test-section">
7394
- <h3>✅ URLs de Desarrollo - SOLUCIONADO</h3>
7395
- <val-text [props]="devUrlsProps"></val-text>
7396
- <p class="note">
7397
- <strong>Esperado:</strong> URLs de localhost, puertos, y rutas de desarrollo se detectan correctamente.
7398
- </p>
7399
- </div>
7400
- </div>
7401
- `, styles: [".comprehensive-test{padding:20px;max-width:1000px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.test-section{margin-bottom:32px;padding:20px;border:2px solid var(--ion-color-success, #2dd36f);border-radius:12px;background:var(--ion-color-success-tint, #42d77d) 10}h2{color:var(--ion-color-primary, #3880ff);margin-bottom:24px;text-align:center}h3{color:var(--ion-color-success, #2dd36f);margin-bottom:16px;font-size:18px;display:flex;align-items:center;gap:8px}.note{margin-top:12px;padding:12px;background:var(--ion-color-light, #f4f5f8);border-radius:8px;font-size:14px;color:var(--ion-color-medium, #92949c);border-left:4px solid var(--ion-color-primary, #3880ff)}.note strong{color:var(--ion-color-dark, #222428)}\n"] }]
7402
- }] });
7403
-
7404
- class CustomContentDemoComponent {
7405
- constructor() {
7406
- this.content = inject(ContentService);
7407
- this.currentLang = 'es';
7408
- // Contenido global predefinido (sin className)
7409
- this.saveText$ = this.content.fromContent({ key: 'save' });
7410
- this.cancelText$ = this.content.fromContent({ key: 'cancel' });
7411
- this.deleteText$ = this.content.fromContent({ key: 'delete' });
7412
- this.loadingText$ = this.content.fromContent({ key: 'loading' });
7413
- // Tu contenido global personalizado (sin className)
7414
- this.dashboardText$ = this.content.fromContent({ key: 'dashboard' });
7415
- this.profileText$ = this.content.fromContent({ key: 'profile' });
7416
- this.settingsText$ = this.content.fromContent({ key: 'settings' });
7417
- this.welcomeText$ = this.content.fromContent({
7418
- key: 'welcome',
7419
- interpolation: { appName: 'Mi Aplicación' },
7420
- });
7421
- // Contenido específico del componente Language (con className)
7422
- this.spanishText$ = this.content.fromContent({
7423
- className: 'Language',
7424
- key: 'spanish',
7425
- });
7426
- this.englishText$ = this.content.fromContent({
7427
- className: 'Language',
7428
- key: 'english',
7429
- });
7430
- this.descriptionText$ = this.content.fromContent({
7431
- className: 'Language',
7432
- key: 'description',
7433
- });
7434
- // Para debug - texto síncrono
7435
- this.saveTextSync = '';
7436
- this.dashboardTextSync = '';
7437
- this.languageDescSync = '';
7438
- }
7439
- ngOnInit() {
7440
- // Obtener idioma actual
7441
- this.content.currentLang$.subscribe(lang => {
7442
- this.currentLang = lang;
7443
- });
7444
- // Obtener textos síncronos para debug
7445
- this.updateSyncTexts();
7446
- // 🔍 DIAGNÓSTICO: Verificar configuración
7447
- this.diagnoseConfiguration();
7448
- }
7449
- switchLanguage() {
7450
- const newLang = this.currentLang === 'es' ? LANGUAGES.EN : LANGUAGES.ES;
7451
- this.content.setLang(newLang);
7452
- // Actualizar textos síncronos después del cambio
7453
- setTimeout(() => {
7454
- this.updateSyncTexts();
7455
- }, 100);
7456
- }
7457
- updateSyncTexts() {
7458
- // Contenido global predefinido
7459
- this.saveTextSync = this.content.getText('save');
7460
- // Tu contenido global personalizado
7461
- this.dashboardTextSync = this.content.getText('dashboard');
7462
- // Contenido específico del componente - SOLUCIÓN TEMPORAL
7463
- // En lugar de usar getText, acceder directamente
7464
- try {
7465
- const langService = this.content.langService;
7466
- const languageContent = langService.content['Language'];
7467
- const currentLang = langService.selectedLang?.value || 'es';
7468
- const classContent = languageContent?.Content?.[currentLang];
7469
- this.languageDescSync = classContent?.['description'] || 'No encontrado';
7470
- }
7471
- catch (error) {
7472
- this.languageDescSync = `Error: ${error}`;
7473
- }
7474
- }
7475
- diagnoseConfiguration() {
7476
- console.log('=== DIAGNÓSTICO DE CONFIGURACIÓN ===');
7477
- // Verificar acceso directo al servicio
7478
- console.log('ContentService available:', !!this.content);
7479
- console.log('Current language:', this.content.currentLang);
7480
- // 🔍 Diagnóstico detallado del contenido Language
7481
- console.log('\n--- DIAGNÓSTICO DETALLADO LANGUAGE ---');
7482
- try {
7483
- // Acceder directamente al LangService
7484
- const langService = this.content.langService;
7485
- console.log('LangService available:', !!langService);
7486
- // Verificar si existe el contenido Language
7487
- const languageContent = langService.content['Language'];
7488
- console.log('Language content exists:', !!languageContent);
7489
- if (languageContent) {
7490
- console.log('Language content structure:', languageContent);
7491
- console.log('Language content.Content:', languageContent.Content);
7492
- // Verificar contenido en español
7493
- const esContent = languageContent.Content?.es;
7494
- console.log('ES content:', esContent);
7495
- console.log('ES description:', esContent?.description);
7496
- // Verificar contenido en inglés
7497
- const enContent = languageContent.Content?.en;
7498
- console.log('EN content:', enContent);
7499
- console.log('EN description:', enContent?.description);
7500
- }
7501
- // Verificar current lang
7502
- const currentLang = langService.selectedLang?.value;
7503
- console.log('Current selected language:', currentLang);
7504
- }
7505
- catch (error) {
7506
- console.log('❌ Error accessing LangService:', error);
7507
- }
7508
- // Intentar acceso síncrono a contenido global predefinido
7509
- try {
7510
- const saveText = this.content.getText('save');
7511
- console.log('✅ Global predefinido (save):', saveText);
7512
- }
7513
- catch (error) {
7514
- console.log('❌ Error global predefinido (save):', error);
7515
- }
7516
- // Intentar acceso síncrono a contenido global personalizado
7517
- try {
7518
- const dashboardText = this.content.getText('dashboard');
7519
- console.log('✅ Global personalizado (dashboard):', dashboardText);
7520
- }
7521
- catch (error) {
7522
- console.log('❌ Error global personalizado (dashboard):', error);
7523
- }
7524
- // Intentar acceso síncrono a contenido de componente
7525
- try {
7526
- const spanishText = this.content.getText('Language', 'spanish');
7527
- console.log('✅ Componente Language (spanish):', spanishText);
7528
- // 🔍 Debug paso a paso para spanish
7529
- const langService = this.content.langService;
7530
- const languageContent = langService.content['Language'];
7531
- const currentLang = langService.selectedLang?.value;
7532
- const classContent = languageContent?.Content[currentLang];
7533
- console.log('🔍 Debug spanish - currentLang:', currentLang);
7534
- console.log('🔍 Debug spanish - classContent:', classContent);
7535
- console.log('🔍 Debug spanish - classContent["spanish"]:', classContent?.['spanish']);
7536
- }
7537
- catch (error) {
7538
- console.log('❌ Error componente Language (spanish):', error);
7539
- }
7540
- // Intentar acceso síncrono a contenido de componente
7541
- try {
7542
- const descriptionText = this.content.getText('Language', 'description');
7543
- console.log('✅ Componente Language (description):', descriptionText);
7544
- // 🔍 Debug paso a paso para description
7545
- const langService = this.content.langService;
7546
- const languageContent = langService.content['Language'];
7547
- const currentLang = langService.selectedLang?.value;
7548
- const classContent = languageContent?.Content[currentLang];
7549
- console.log('🔍 Debug description - currentLang:', currentLang);
7550
- console.log('🔍 Debug description - classContent:', classContent);
7551
- console.log('🔍 Debug description - classContent["description"]:', classContent?.['description']);
7552
- }
7553
- catch (error) {
7554
- console.log('❌ Error componente Language (description):', error);
7555
- }
7556
- }
7557
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomContentDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7558
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CustomContentDemoComponent, isStandalone: true, selector: "app-custom-content-demo", ngImport: i0, template: `
7559
- <ion-card>
7560
- <ion-card-header>
7561
- <ion-card-title>Demo de Contenido Personalizado</ion-card-title>
7562
- </ion-card-header>
7563
-
7564
- <ion-card-content>
7565
- <!-- Contenido global predefinido -->
7566
- <div style="margin-bottom: 20px;">
7567
- <h3>Contenido Global Predefinido:</h3>
7568
- <ion-button>{{ saveText$ | async }}</ion-button>
7569
- <ion-button color="medium">{{ cancelText$ | async }}</ion-button>
7570
- <ion-button color="danger">{{ deleteText$ | async }}</ion-button>
7571
- <p><strong>Estado:</strong> {{ loadingText$ | async }}</p>
7572
- </div>
7573
-
7574
- <!-- Tu contenido global personalizado -->
7575
- <div style="margin-bottom: 20px;">
7576
- <h3>Tu Contenido Global Personalizado:</h3>
7577
- <p><strong>Sección:</strong> {{ dashboardText$ | async }}</p>
7578
- <p><strong>Usuario:</strong> {{ profileText$ | async }}</p>
7579
- <p><strong>Config:</strong> {{ settingsText$ | async }}</p>
7580
- <p>{{ welcomeText$ | async }}</p>
7581
- </div>
7582
-
7583
- <!-- Contenido específico del componente Language -->
7584
- <div style="margin-bottom: 20px;">
7585
- <h3>Contenido del Componente Language:</h3>
7586
- <ion-item>
7587
- <ion-label> <strong>Español:</strong> {{ spanishText$ | async }} </ion-label>
7588
- </ion-item>
7589
- <ion-item>
7590
- <ion-label> <strong>Inglés:</strong> {{ englishText$ | async }} </ion-label>
7591
- </ion-item>
7592
- <p>
7593
- <em>{{ descriptionText$ | async }}</em>
7594
- </p>
7595
- </div>
7596
-
7597
- <!-- Botón para cambiar idioma -->
7598
- <div>
7599
- <h3>Control de Idioma:</h3>
7600
- <ion-button (click)="switchLanguage()" color="secondary">
7601
- Cambiar a {{ currentLang === 'es' ? 'English' : 'Español' }}
7602
- </ion-button>
7603
- <p>
7604
- <small>Idioma actual: {{ currentLang }}</small>
7605
- </p>
7606
- </div>
7607
-
7608
- <!-- Debug info -->
7609
- <div style="margin-top: 20px; padding: 10px; background: #f5f5f5; border-radius: 4px;">
7610
- <h4>Debug Info:</h4>
7611
- <p><strong>Save (sync):</strong> {{ saveTextSync }}</p>
7612
- <p><strong>Dashboard (sync):</strong> {{ dashboardTextSync }}</p>
7613
- <p><strong>Language Description (sync):</strong> {{ languageDescSync }}</p>
7614
- </div>
7615
- </ion-card-content>
7616
- </ion-card>
7617
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }] }); }
7618
- }
7619
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomContentDemoComponent, decorators: [{
7620
- type: Component,
7621
- args: [{
7622
- selector: 'app-custom-content-demo',
7623
- standalone: true,
7624
- imports: [CommonModule, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonButton, IonItem, IonLabel],
7625
- template: `
7626
- <ion-card>
7627
- <ion-card-header>
7628
- <ion-card-title>Demo de Contenido Personalizado</ion-card-title>
7629
- </ion-card-header>
7630
-
7631
- <ion-card-content>
7632
- <!-- Contenido global predefinido -->
7633
- <div style="margin-bottom: 20px;">
7634
- <h3>Contenido Global Predefinido:</h3>
7635
- <ion-button>{{ saveText$ | async }}</ion-button>
7636
- <ion-button color="medium">{{ cancelText$ | async }}</ion-button>
7637
- <ion-button color="danger">{{ deleteText$ | async }}</ion-button>
7638
- <p><strong>Estado:</strong> {{ loadingText$ | async }}</p>
7639
- </div>
7640
-
7641
- <!-- Tu contenido global personalizado -->
7642
- <div style="margin-bottom: 20px;">
7643
- <h3>Tu Contenido Global Personalizado:</h3>
7644
- <p><strong>Sección:</strong> {{ dashboardText$ | async }}</p>
7645
- <p><strong>Usuario:</strong> {{ profileText$ | async }}</p>
7646
- <p><strong>Config:</strong> {{ settingsText$ | async }}</p>
7647
- <p>{{ welcomeText$ | async }}</p>
7648
- </div>
7649
-
7650
- <!-- Contenido específico del componente Language -->
7651
- <div style="margin-bottom: 20px;">
7652
- <h3>Contenido del Componente Language:</h3>
7653
- <ion-item>
7654
- <ion-label> <strong>Español:</strong> {{ spanishText$ | async }} </ion-label>
7655
- </ion-item>
7656
- <ion-item>
7657
- <ion-label> <strong>Inglés:</strong> {{ englishText$ | async }} </ion-label>
7658
- </ion-item>
7659
- <p>
7660
- <em>{{ descriptionText$ | async }}</em>
7661
- </p>
7662
- </div>
7663
-
7664
- <!-- Botón para cambiar idioma -->
7665
- <div>
7666
- <h3>Control de Idioma:</h3>
7667
- <ion-button (click)="switchLanguage()" color="secondary">
7668
- Cambiar a {{ currentLang === 'es' ? 'English' : 'Español' }}
7669
- </ion-button>
7670
- <p>
7671
- <small>Idioma actual: {{ currentLang }}</small>
7672
- </p>
7673
- </div>
7674
-
7675
- <!-- Debug info -->
7676
- <div style="margin-top: 20px; padding: 10px; background: #f5f5f5; border-radius: 4px;">
7677
- <h4>Debug Info:</h4>
7678
- <p><strong>Save (sync):</strong> {{ saveTextSync }}</p>
7679
- <p><strong>Dashboard (sync):</strong> {{ dashboardTextSync }}</p>
7680
- <p><strong>Language Description (sync):</strong> {{ languageDescSync }}</p>
7681
- </div>
7682
- </ion-card-content>
7683
- </ion-card>
7684
- `,
7685
- }]
7686
- }] });
7280
+ const text = {
7281
+ es: {
7282
+ spanish: 'Español',
7283
+ english: 'Inglés',
7284
+ },
7285
+ en: {
7286
+ spanish: 'Spanish',
7287
+ english: 'English',
7288
+ },
7289
+ };
7290
+ var LangSettings = new TextContent(text);
7687
7291
 
7688
7292
  /**
7689
- * Componente de demostración para val-display con contenido reactivo.
7690
- * Muestra diferentes patrones de uso y casos de ejemplo.
7691
- */
7692
- class DisplayDemoComponent {
7693
- constructor(contentService, langService) {
7694
- this.contentService = contentService;
7695
- this.langService = langService;
7696
- // Contador para ejemplos dinámicos
7697
- this.counter = 0;
7698
- // Configuración del selector de idioma
7699
- this.languageSelectorProps = {
7700
- showLabel: true,
7701
- labelConfig: {
7702
- className: '_global',
7703
- key: 'language',
7704
- fallback: 'Idioma',
7705
- },
7706
- showFlags: true,
7707
- color: 'primary',
7708
- size: 'default',
7709
- fill: 'outline',
7710
- };
7711
- // Configuraciones de ejemplo - ESTÁTICAS
7712
- this.smallStaticDisplay = {
7713
- content: 'Texto pequeño estático',
7714
- color: 'dark',
7715
- size: 'small',
7716
- };
7717
- this.mediumStaticDisplay = {
7718
- content: 'Texto mediano estático',
7719
- color: 'dark',
7720
- size: 'medium',
7721
- };
7722
- this.largeStaticDisplay = {
7723
- content: 'Texto grande estático',
7724
- color: 'dark',
7725
- size: 'large',
7726
- };
7727
- this.xlargeStaticDisplay = {
7728
- content: 'Texto extra grande estático',
7729
- color: 'dark',
7730
- size: 'xlarge',
7731
- };
7732
- // Ejemplos de colores estáticos
7733
- this.primaryDisplay = {
7734
- content: 'Texto primario',
7735
- color: 'primary',
7736
- size: 'medium',
7737
- };
7738
- this.secondaryDisplay = {
7739
- content: 'Texto secundario',
7740
- color: 'secondary',
7741
- size: 'medium',
7742
- };
7743
- this.successDisplay = {
7744
- content: 'Texto de éxito',
7745
- color: 'success',
7746
- size: 'medium',
7747
- };
7748
- this.warningDisplay = {
7749
- content: 'Texto de advertencia',
7750
- color: 'warning',
7751
- size: 'medium',
7752
- };
7753
- this.dangerDisplay = {
7754
- content: 'Texto de peligro',
7755
- color: 'danger',
7756
- size: 'medium',
7757
- };
7758
- // Configuraciones de ejemplo - REACTIVAS
7759
- this.welcomeDisplay = {
7760
- contentConfig: {
7761
- className: 'displayDemo',
7762
- key: 'welcomeTitle',
7763
- fallback: 'Bienvenido a la aplicación',
7764
- },
7765
- color: 'primary',
7766
- size: 'xlarge',
7767
- };
7768
- this.descriptionDisplay = {
7769
- contentConfig: {
7770
- className: 'displayDemo',
7771
- key: 'welcomeDescription',
7772
- fallback: 'Esta es una descripción de ejemplo',
7773
- },
7774
- color: 'medium',
7775
- size: 'medium',
7776
- };
7777
- this.statusDisplay = {
7778
- contentConfig: {
7779
- className: 'displayDemo',
7780
- key: 'statusOnline',
7781
- fallback: 'En línea',
7782
- },
7783
- color: 'success',
7784
- size: 'small',
7785
- };
7786
- // Ejemplos con interpolación
7787
- this.userWelcomeDisplay = {
7788
- contentConfig: {
7789
- className: 'displayDemo',
7790
- key: 'welcomeUser',
7791
- fallback: 'Hola, {{userName}}!',
7792
- interpolation: {
7793
- userName: 'Juan Pérez',
7794
- },
7795
- },
7796
- color: 'tertiary',
7797
- size: 'large',
7798
- };
7799
- this.counterDisplay = {
7800
- contentConfig: {
7801
- className: 'displayDemo',
7802
- key: 'counterCurrent',
7803
- fallback: 'Contador: {{count}}',
7804
- interpolation: {
7805
- count: this.counter,
7806
- },
7807
- },
7808
- color: 'secondary',
7809
- size: 'medium',
7810
- };
7811
- // Ejemplos con claves faltantes para demostrar fallbacks
7812
- this.missingKeyDisplay = {
7813
- contentConfig: {
7814
- className: 'displayDemo',
7815
- key: 'this.key.does.not.exist',
7816
- fallback: 'Esta clave no existe, pero tengo fallback',
7817
- },
7818
- color: 'warning',
7819
- size: 'medium',
7820
- };
7821
- this.noFallbackDisplay = {
7822
- contentConfig: {
7823
- className: 'displayDemo',
7824
- key: 'another.missing.key',
7825
- // Sin fallback - usará la clave como fallback
7826
- },
7827
- color: 'danger',
7828
- size: 'small',
7829
- };
7830
- // Ejemplos mixtos
7831
- this.staticMixedDisplay = {
7832
- content: 'Este es contenido estático (no cambia con el idioma)',
7833
- color: 'dark',
7834
- size: 'medium',
7835
- };
7836
- this.reactiveMixedDisplay = {
7837
- contentConfig: {
7838
- className: 'displayDemo',
7839
- key: 'mixedReactive',
7840
- fallback: 'Este contenido sí cambia con el idioma',
7841
- },
7842
- color: 'primary',
7843
- size: 'medium',
7844
- };
7845
- // Ejemplo dinámico que se actualiza
7846
- this.dynamicCounterDisplay = {
7847
- contentConfig: {
7848
- className: 'displayDemo',
7849
- key: 'dynamicContent',
7850
- fallback: 'Clics: {{count}}',
7851
- interpolation: {
7852
- count: this.counter,
7853
- },
7854
- },
7855
- color: 'tertiary',
7856
- size: 'large',
7857
- };
7858
- }
7859
- ngOnInit() {
7860
- this.initializeContent();
7861
- this.initializeLanguageState();
7862
- }
7863
- initializeContent() {
7864
- // Contenido de la página
7865
- this.demoTitle$ = this.contentService.fromContent({
7866
- className: 'displayDemo',
7867
- key: 'pageTitle',
7868
- fallback: 'Demostración del Componente Display',
7869
- });
7870
- this.languageLabel$ = this.contentService.fromContent({
7871
- className: '_global',
7872
- key: 'language',
7873
- fallback: 'Idioma',
7874
- });
7875
- this.staticSectionTitle$ = this.contentService.fromContent({
7876
- className: 'displayDemo',
7877
- key: 'sectionsStatic',
7878
- fallback: 'Ejemplos Estáticos',
7879
- });
7880
- this.reactiveSectionTitle$ = this.contentService.fromContent({
7881
- className: 'displayDemo',
7882
- key: 'sectionsReactive',
7883
- fallback: 'Ejemplos Reactivos',
7884
- });
7885
- this.mixedSectionTitle$ = this.contentService.fromContent({
7886
- className: 'displayDemo',
7887
- key: 'sectionsMixed',
7888
- fallback: 'Ejemplos Mixtos',
7889
- });
7890
- this.dynamicSectionTitle$ = this.contentService.fromContent({
7891
- className: 'displayDemo',
7892
- key: 'sectionsDynamic',
7893
- fallback: 'Ejemplos Dinámicos',
7894
- });
7895
- this.analysisTitle$ = this.contentService.fromContent({
7896
- className: 'displayDemo',
7897
- key: 'sectionsAnalysis',
7898
- fallback: 'Análisis de Idioma',
7899
- });
7900
- this.reactiveContentTitle$ = this.contentService.fromContent({
7901
- className: 'displayDemo',
7902
- key: 'subsectionsReactiveContent',
7903
- fallback: 'Contenido reactivo básico:',
7904
- });
7905
- this.interpolationTitle$ = this.contentService.fromContent({
7906
- className: 'displayDemo',
7907
- key: 'subsectionsInterpolation',
7908
- fallback: 'Contenido con interpolación:',
7909
- });
7910
- this.fallbackTitle$ = this.contentService.fromContent({
7911
- className: 'displayDemo',
7912
- key: 'subsectionsFallback',
7913
- fallback: 'Demostración de fallbacks:',
7914
- });
7915
- this.mixedContentTitle$ = this.contentService.fromContent({
7916
- className: 'displayDemo',
7917
- key: 'subsectionsMixedContent',
7918
- fallback: 'Contenido estático vs reactivo:',
7919
- });
7920
- this.dynamicContentTitle$ = this.contentService.fromContent({
7921
- className: 'displayDemo',
7922
- key: 'subsectionsDynamicContent',
7923
- fallback: 'Contenido que se actualiza dinámicamente:',
7924
- });
7925
- this.updateButtonText$ = this.contentService.fromContent({
7926
- className: 'displayDemo',
7927
- key: 'buttonsUpdateCounter',
7928
- fallback: 'Actualizar Contador',
7929
- });
7930
- this.currentLangLabel$ = this.contentService.fromContent({
7931
- className: 'displayDemo',
7932
- key: 'analysisCurrentLanguage',
7933
- fallback: 'Idioma actual',
7934
- });
7935
- this.availableLangsLabel$ = this.contentService.fromContent({
7936
- className: 'displayDemo',
7937
- key: 'analysisAvailableLanguages',
7938
- fallback: 'Idiomas disponibles',
7939
- });
7940
- }
7941
- initializeLanguageState() {
7942
- this.currentLanguage$ = this.langService.currentLang$;
7943
- this.availableLanguages$ = this.langService.currentLang$.pipe(map$1(() => this.langService.availableLangs));
7944
- }
7945
- changeLanguage(language) {
7946
- this.langService.setLang(language);
7947
- }
7948
- onLanguageChange(language) {
7949
- console.log('Language changed to:', language);
7950
- // El language selector ya maneja el cambio de idioma internamente
7951
- // pero podemos agregar lógica adicional aquí si es necesario
7952
- }
7953
- updateCounter() {
7954
- this.counter++;
7955
- // Actualizar los displays que usan el contador
7956
- this.counterDisplay = {
7957
- ...this.counterDisplay,
7958
- contentConfig: {
7959
- ...this.counterDisplay.contentConfig,
7960
- interpolation: {
7961
- count: this.counter,
7962
- },
7963
- },
7964
- };
7965
- this.dynamicCounterDisplay = {
7966
- ...this.dynamicCounterDisplay,
7967
- contentConfig: {
7968
- ...this.dynamicCounterDisplay.contentConfig,
7969
- interpolation: {
7970
- count: this.counter,
7971
- },
7972
- },
7973
- };
7974
- }
7975
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DisplayDemoComponent, deps: [{ token: ContentService }, { token: LangService }], target: i0.ɵɵFactoryTarget.Component }); }
7976
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DisplayDemoComponent, isStandalone: true, selector: "val-display-demo", ngImport: i0, template: `
7977
- <div class="display-demo">
7978
- <ion-card>
7979
- <ion-card-header>
7980
- <ion-card-title>{{ demoTitle$ | async }}</ion-card-title>
7981
- </ion-card-header>
7982
-
7983
- <ion-card-content>
7984
- <!-- Selector de idioma -->
7985
- <div class="language-selector-container">
7986
- <val-language-selector [props]="languageSelectorProps" (languageChange)="onLanguageChange($event)">
7987
- </val-language-selector>
7988
- </div>
7989
-
7990
- <!-- Ejemplos estáticos -->
7991
- <div class="section">
7992
- <h3>{{ staticSectionTitle$ | async }}</h3>
7993
-
7994
- <div class="example-group">
7995
- <h4>Diferentes tamaños:</h4>
7996
- <val-display [props]="smallStaticDisplay"></val-display>
7997
- <val-display [props]="mediumStaticDisplay"></val-display>
7998
- <val-display [props]="largeStaticDisplay"></val-display>
7999
- <val-display [props]="xlargeStaticDisplay"></val-display>
8000
- </div>
8001
-
8002
- <div class="example-group">
8003
- <h4>Diferentes colores:</h4>
8004
- <val-display [props]="primaryDisplay"></val-display>
8005
- <val-display [props]="secondaryDisplay"></val-display>
8006
- <val-display [props]="successDisplay"></val-display>
8007
- <val-display [props]="warningDisplay"></val-display>
8008
- <val-display [props]="dangerDisplay"></val-display>
8009
- </div>
8010
- </div>
8011
-
8012
- <!-- Ejemplos reactivos -->
8013
- <div class="section">
8014
- <h3>{{ reactiveSectionTitle$ | async }}</h3>
8015
-
8016
- <div class="example-group">
8017
- <h4>{{ reactiveContentTitle$ | async }}</h4>
8018
- <val-display [props]="welcomeDisplay"></val-display>
8019
- <val-display [props]="descriptionDisplay"></val-display>
8020
- <val-display [props]="statusDisplay"></val-display>
8021
- </div>
8022
-
8023
- <div class="example-group">
8024
- <h4>{{ interpolationTitle$ | async }}</h4>
8025
- <val-display [props]="userWelcomeDisplay"></val-display>
8026
- <val-display [props]="counterDisplay"></val-display>
8027
- </div>
8028
-
8029
- <div class="example-group">
8030
- <h4>{{ fallbackTitle$ | async }}</h4>
8031
- <val-display [props]="missingKeyDisplay"></val-display>
8032
- <val-display [props]="noFallbackDisplay"></val-display>
8033
- </div>
8034
- </div>
8035
-
8036
- <!-- Ejemplos mixtos -->
8037
- <div class="section">
8038
- <h3>{{ mixedSectionTitle$ | async }}</h3>
8039
-
8040
- <div class="example-group">
8041
- <h4>{{ mixedContentTitle$ | async }}</h4>
8042
- <div class="mixed-examples">
8043
- <val-display [props]="staticMixedDisplay"></val-display>
8044
- <val-display [props]="reactiveMixedDisplay"></val-display>
8045
- </div>
8046
- </div>
8047
- </div>
8048
-
8049
- <!-- Ejemplos dinámicos -->
8050
- <div class="section">
8051
- <h3>{{ dynamicSectionTitle$ | async }}</h3>
8052
-
8053
- <div class="example-group">
8054
- <h4>{{ dynamicContentTitle$ | async }}</h4>
8055
- <ion-button (click)="updateCounter()" color="primary">
8056
- {{ updateButtonText$ | async }}
8057
- </ion-button>
8058
- <val-display [props]="dynamicCounterDisplay"></val-display>
8059
- </div>
8060
- </div>
8061
-
8062
- <!-- Análisis de contenido -->
8063
- <div class="section">
8064
- <h3>{{ analysisTitle$ | async }}</h3>
8065
- <div class="analysis-info">
8066
- <p>
8067
- <strong>{{ currentLangLabel$ | async }}:</strong> {{ currentLanguage$ | async | uppercase }}
8068
- </p>
8069
- <p>
8070
- <strong>{{ availableLangsLabel$ | async }}:</strong>
8071
- {{ (availableLanguages$ | async)?.join(', ') | uppercase }}
8072
- </p>
8073
- </div>
8074
- </div>
8075
- </ion-card-content>
8076
- </ion-card>
8077
- </div>
8078
- `, isInline: true, styles: [".display-demo{padding:16px}.language-selector-container{margin:16px 0;padding:12px;background:var(--ion-color-step-50);border-radius:8px}.section{margin:24px 0;border-bottom:1px solid var(--ion-color-light);padding-bottom:16px}.example-group{margin:16px 0;padding:12px;background:var(--ion-color-light);border-radius:8px}.example-group h4{margin:0 0 12px;color:var(--ion-color-medium)}.mixed-examples{display:flex;flex-direction:column;gap:8px}.analysis-info{background:var(--ion-color-step-50);padding:16px;border-radius:8px;margin-top:16px}val-display{display:block;margin:8px 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: LanguageSelectorComponent, selector: "val-language-selector", inputs: ["props"], outputs: ["languageChange"] }] }); }
8079
- }
8080
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DisplayDemoComponent, decorators: [{
8081
- type: Component,
8082
- args: [{ selector: 'val-display-demo', standalone: true, imports: [
8083
- CommonModule,
8084
- IonCard,
8085
- IonCardContent,
8086
- IonCardHeader,
8087
- IonCardTitle,
8088
- IonButton,
8089
- DisplayComponent,
8090
- LanguageSelectorComponent,
8091
- ], template: `
8092
- <div class="display-demo">
8093
- <ion-card>
8094
- <ion-card-header>
8095
- <ion-card-title>{{ demoTitle$ | async }}</ion-card-title>
8096
- </ion-card-header>
8097
-
8098
- <ion-card-content>
8099
- <!-- Selector de idioma -->
8100
- <div class="language-selector-container">
8101
- <val-language-selector [props]="languageSelectorProps" (languageChange)="onLanguageChange($event)">
8102
- </val-language-selector>
8103
- </div>
8104
-
8105
- <!-- Ejemplos estáticos -->
8106
- <div class="section">
8107
- <h3>{{ staticSectionTitle$ | async }}</h3>
8108
-
8109
- <div class="example-group">
8110
- <h4>Diferentes tamaños:</h4>
8111
- <val-display [props]="smallStaticDisplay"></val-display>
8112
- <val-display [props]="mediumStaticDisplay"></val-display>
8113
- <val-display [props]="largeStaticDisplay"></val-display>
8114
- <val-display [props]="xlargeStaticDisplay"></val-display>
8115
- </div>
8116
-
8117
- <div class="example-group">
8118
- <h4>Diferentes colores:</h4>
8119
- <val-display [props]="primaryDisplay"></val-display>
8120
- <val-display [props]="secondaryDisplay"></val-display>
8121
- <val-display [props]="successDisplay"></val-display>
8122
- <val-display [props]="warningDisplay"></val-display>
8123
- <val-display [props]="dangerDisplay"></val-display>
8124
- </div>
8125
- </div>
8126
-
8127
- <!-- Ejemplos reactivos -->
8128
- <div class="section">
8129
- <h3>{{ reactiveSectionTitle$ | async }}</h3>
8130
-
8131
- <div class="example-group">
8132
- <h4>{{ reactiveContentTitle$ | async }}</h4>
8133
- <val-display [props]="welcomeDisplay"></val-display>
8134
- <val-display [props]="descriptionDisplay"></val-display>
8135
- <val-display [props]="statusDisplay"></val-display>
8136
- </div>
8137
-
8138
- <div class="example-group">
8139
- <h4>{{ interpolationTitle$ | async }}</h4>
8140
- <val-display [props]="userWelcomeDisplay"></val-display>
8141
- <val-display [props]="counterDisplay"></val-display>
8142
- </div>
8143
-
8144
- <div class="example-group">
8145
- <h4>{{ fallbackTitle$ | async }}</h4>
8146
- <val-display [props]="missingKeyDisplay"></val-display>
8147
- <val-display [props]="noFallbackDisplay"></val-display>
8148
- </div>
8149
- </div>
8150
-
8151
- <!-- Ejemplos mixtos -->
8152
- <div class="section">
8153
- <h3>{{ mixedSectionTitle$ | async }}</h3>
8154
-
8155
- <div class="example-group">
8156
- <h4>{{ mixedContentTitle$ | async }}</h4>
8157
- <div class="mixed-examples">
8158
- <val-display [props]="staticMixedDisplay"></val-display>
8159
- <val-display [props]="reactiveMixedDisplay"></val-display>
8160
- </div>
8161
- </div>
8162
- </div>
8163
-
8164
- <!-- Ejemplos dinámicos -->
8165
- <div class="section">
8166
- <h3>{{ dynamicSectionTitle$ | async }}</h3>
8167
-
8168
- <div class="example-group">
8169
- <h4>{{ dynamicContentTitle$ | async }}</h4>
8170
- <ion-button (click)="updateCounter()" color="primary">
8171
- {{ updateButtonText$ | async }}
8172
- </ion-button>
8173
- <val-display [props]="dynamicCounterDisplay"></val-display>
8174
- </div>
8175
- </div>
8176
-
8177
- <!-- Análisis de contenido -->
8178
- <div class="section">
8179
- <h3>{{ analysisTitle$ | async }}</h3>
8180
- <div class="analysis-info">
8181
- <p>
8182
- <strong>{{ currentLangLabel$ | async }}:</strong> {{ currentLanguage$ | async | uppercase }}
8183
- </p>
8184
- <p>
8185
- <strong>{{ availableLangsLabel$ | async }}:</strong>
8186
- {{ (availableLanguages$ | async)?.join(', ') | uppercase }}
8187
- </p>
8188
- </div>
8189
- </div>
8190
- </ion-card-content>
8191
- </ion-card>
8192
- </div>
8193
- `, styles: [".display-demo{padding:16px}.language-selector-container{margin:16px 0;padding:12px;background:var(--ion-color-step-50);border-radius:8px}.section{margin:24px 0;border-bottom:1px solid var(--ion-color-light);padding-bottom:16px}.example-group{margin:16px 0;padding:12px;background:var(--ion-color-light);border-radius:8px}.example-group h4{margin:0 0 12px;color:var(--ion-color-medium)}.mixed-examples{display:flex;flex-direction:column;gap:8px}.analysis-info{background:var(--ion-color-step-50);padding:16px;border-radius:8px;margin-top:16px}val-display{display:block;margin:8px 0}\n"] }]
8194
- }], ctorParameters: () => [{ type: ContentService }, { type: LangService }] });
8195
-
8196
- /**
8197
- * Ejemplo rápido de uso del componente val-display con contenido reactivo
8198
- */
8199
- class DisplayExampleComponent {
8200
- constructor() {
8201
- // ✅ Ejemplos de contenido estático
8202
- this.staticTitle = {
8203
- content: 'Este es un título estático',
8204
- color: 'primary',
8205
- size: 'xlarge',
8206
- };
8207
- this.staticSubtitle = {
8208
- content: 'Este es un subtítulo que no cambia',
8209
- color: 'medium',
8210
- size: 'large',
8211
- };
8212
- // ✅ Ejemplos de contenido reactivo (requiere configuración de i18n)
8213
- this.reactiveWelcome = {
8214
- contentConfig: {
8215
- className: 'displayExample',
8216
- key: 'welcome.title',
8217
- fallback: 'Bienvenido a la aplicación',
8218
- },
8219
- color: 'primary',
8220
- size: 'xlarge',
8221
- };
8222
- this.reactiveDescription = {
8223
- contentConfig: {
8224
- className: 'displayExample',
8225
- key: 'welcome.description',
8226
- fallback: 'Esta descripción cambia según el idioma',
8227
- },
8228
- color: 'dark',
8229
- size: 'medium',
8230
- };
8231
- // ✅ Ejemplos con interpolación de variables
8232
- this.userGreeting = {
8233
- contentConfig: {
8234
- className: 'displayExample',
8235
- key: 'user.greeting',
8236
- fallback: 'Hola, {{name}}! Tienes {{messages}} mensajes.',
8237
- interpolation: {
8238
- name: 'María',
8239
- messages: 5,
8240
- },
8241
- },
8242
- color: 'tertiary',
8243
- size: 'large',
8244
- };
8245
- this.statusMessage = {
8246
- contentConfig: {
8247
- className: 'displayExample',
8248
- key: 'status.online',
8249
- fallback: 'Estado: {{status}} desde {{time}}',
8250
- interpolation: {
8251
- status: 'En línea',
8252
- time: '10:30 AM',
8253
- },
8254
- },
8255
- color: 'success',
8256
- size: 'small',
8257
- };
8258
- // ✅ Ejemplos de diferentes tamaños
8259
- this.smallText = {
8260
- content: 'Texto pequeño (small)',
8261
- color: 'dark',
8262
- size: 'small',
8263
- };
8264
- this.mediumText = {
8265
- content: 'Texto mediano (medium)',
8266
- color: 'dark',
8267
- size: 'medium',
8268
- };
8269
- this.largeText = {
8270
- content: 'Texto grande (large)',
8271
- color: 'dark',
8272
- size: 'large',
8273
- };
8274
- this.xlargeText = {
8275
- content: 'Texto extra grande (xlarge)',
8276
- color: 'dark',
8277
- size: 'xlarge',
8278
- };
8279
- // ✅ Ejemplos de diferentes colores
8280
- this.primaryText = {
8281
- content: 'Texto color primary',
8282
- color: 'primary',
8283
- size: 'medium',
8284
- };
8285
- this.successText = {
8286
- content: 'Texto color success',
8287
- color: 'success',
8288
- size: 'medium',
8289
- };
8290
- this.warningText = {
8291
- content: 'Texto color warning',
8292
- color: 'warning',
8293
- size: 'medium',
8294
- };
8295
- this.dangerText = {
8296
- content: 'Texto color danger',
8297
- color: 'danger',
8298
- size: 'medium',
8299
- };
8300
- }
8301
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DisplayExampleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8302
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DisplayExampleComponent, isStandalone: true, selector: "app-display-example", ngImport: i0, template: `
8303
- <div class="display-examples">
8304
- <h2>Ejemplos de val-display</h2>
8305
-
8306
- <!-- Contenido estático -->
8307
- <div class="section">
8308
- <h3>Contenido Estático</h3>
8309
- <val-display [props]="staticTitle"></val-display>
8310
- <val-display [props]="staticSubtitle"></val-display>
8311
- </div>
8312
-
8313
- <!-- Contenido reactivo -->
8314
- <div class="section">
8315
- <h3>Contenido Reactivo</h3>
8316
- <val-display [props]="reactiveWelcome"></val-display>
8317
- <val-display [props]="reactiveDescription"></val-display>
8318
- </div>
8319
-
8320
- <!-- Contenido con interpolación -->
8321
- <div class="section">
8322
- <h3>Contenido con Variables</h3>
8323
- <val-display [props]="userGreeting"></val-display>
8324
- <val-display [props]="statusMessage"></val-display>
8325
- </div>
8326
-
8327
- <!-- Diferentes tamaños -->
8328
- <div class="section">
8329
- <h3>Diferentes Tamaños</h3>
8330
- <val-display [props]="smallText"></val-display>
8331
- <val-display [props]="mediumText"></val-display>
8332
- <val-display [props]="largeText"></val-display>
8333
- <val-display [props]="xlargeText"></val-display>
8334
- </div>
8335
-
8336
- <!-- Diferentes colores -->
8337
- <div class="section">
8338
- <h3>Diferentes Colores</h3>
8339
- <val-display [props]="primaryText"></val-display>
8340
- <val-display [props]="successText"></val-display>
8341
- <val-display [props]="warningText"></val-display>
8342
- <val-display [props]="dangerText"></val-display>
8343
- </div>
8344
- </div>
8345
- `, isInline: true, styles: [".display-examples{padding:20px;max-width:800px;margin:0 auto}.section{margin:30px 0;padding:20px;border:1px solid var(--ion-color-light);border-radius:8px;background:var(--ion-color-step-50)}.section h3{margin:0 0 15px;color:var(--ion-color-primary)}val-display{display:block;margin:10px 0}\n"], dependencies: [{ kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }] }); }
8346
- }
8347
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DisplayExampleComponent, decorators: [{
8348
- type: Component,
8349
- args: [{ selector: 'app-display-example', standalone: true, imports: [DisplayComponent], template: `
8350
- <div class="display-examples">
8351
- <h2>Ejemplos de val-display</h2>
8352
-
8353
- <!-- Contenido estático -->
8354
- <div class="section">
8355
- <h3>Contenido Estático</h3>
8356
- <val-display [props]="staticTitle"></val-display>
8357
- <val-display [props]="staticSubtitle"></val-display>
8358
- </div>
8359
-
8360
- <!-- Contenido reactivo -->
8361
- <div class="section">
8362
- <h3>Contenido Reactivo</h3>
8363
- <val-display [props]="reactiveWelcome"></val-display>
8364
- <val-display [props]="reactiveDescription"></val-display>
8365
- </div>
8366
-
8367
- <!-- Contenido con interpolación -->
8368
- <div class="section">
8369
- <h3>Contenido con Variables</h3>
8370
- <val-display [props]="userGreeting"></val-display>
8371
- <val-display [props]="statusMessage"></val-display>
8372
- </div>
8373
-
8374
- <!-- Diferentes tamaños -->
8375
- <div class="section">
8376
- <h3>Diferentes Tamaños</h3>
8377
- <val-display [props]="smallText"></val-display>
8378
- <val-display [props]="mediumText"></val-display>
8379
- <val-display [props]="largeText"></val-display>
8380
- <val-display [props]="xlargeText"></val-display>
8381
- </div>
8382
-
8383
- <!-- Diferentes colores -->
8384
- <div class="section">
8385
- <h3>Diferentes Colores</h3>
8386
- <val-display [props]="primaryText"></val-display>
8387
- <val-display [props]="successText"></val-display>
8388
- <val-display [props]="warningText"></val-display>
8389
- <val-display [props]="dangerText"></val-display>
8390
- </div>
8391
- </div>
8392
- `, styles: [".display-examples{padding:20px;max-width:800px;margin:0 auto}.section{margin:30px 0;padding:20px;border:1px solid var(--ion-color-light);border-radius:8px;background:var(--ion-color-step-50)}.section h3{margin:0 0 15px;color:var(--ion-color-primary)}val-display{display:block;margin:10px 0}\n"] }]
8393
- }] });
8394
-
8395
- /**
8396
- * LinkProcessingExampleComponent - Componente de ejemplo que demuestra el procesamiento automático de enlaces.
8397
- *
8398
- * Este componente muestra diferentes casos de uso para el procesamiento automático de enlaces
8399
- * en el componente val-text, incluyendo enlaces externos, rutas internas y configuraciones personalizadas.
8400
- *
8401
- * @example Uso en template:
8402
- * ```html
8403
- * <val-link-processing-example></val-link-processing-example>
8404
- * ```
8405
- */
8406
- class LinkProcessingExampleComponent {
8407
- constructor() {
8408
- this.basicTextProps = {
8409
- content: 'Este texto contiene https://angular.io y /dashboard pero no se procesan como enlaces.',
8410
- size: 'medium',
8411
- color: 'dark',
8412
- bold: false,
8413
- processLinks: false,
8414
- };
8415
- this.basicLinksProps = {
8416
- content: 'Visita https://angular.io para documentación o ve a /dashboard para el panel principal.',
8417
- size: 'medium',
8418
- color: 'dark',
8419
- bold: false,
8420
- processLinks: true,
8421
- };
8422
- this.customLinksProps = {
8423
- content: 'Enlaces personalizados: https://github.com/angular/angular y /profile/settings',
8424
- size: 'medium',
8425
- color: 'dark',
8426
- bold: false,
8427
- processLinks: true,
8428
- linkConfig: {
8429
- openExternalInNewTab: true,
8430
- openInternalInNewTab: false,
8431
- linkClass: 'custom-link-style',
8432
- externalLinkClass: 'external-custom',
8433
- internalLinkClass: 'internal-custom',
8434
- },
8435
- };
8436
- this.mixedLinksProps = {
8437
- content: 'Consulta la documentación en https://ionicframework.com/docs, revisa el código en https://github.com/ionic-team/ionic-framework, o navega a /components/buttons para ejemplos internos.',
8438
- size: 'medium',
8439
- color: 'dark',
8440
- bold: false,
8441
- processLinks: true,
8442
- linkConfig: {
8443
- openExternalInNewTab: true,
8444
- openInternalInNewTab: false,
8445
- linkClass: 'processed-link',
8446
- externalLinkClass: 'external-link',
8447
- internalLinkClass: 'internal-link',
8448
- },
8449
- };
8450
- this.sameTabLinksProps = {
8451
- content: 'Estos enlaces no abren en nueva pestaña: https://example.com y /home',
8452
- size: 'medium',
8453
- color: 'dark',
8454
- bold: false,
8455
- processLinks: true,
8456
- linkConfig: {
8457
- openExternalInNewTab: false,
8458
- openInternalInNewTab: false,
8459
- linkClass: 'same-tab-link',
8460
- externalLinkClass: 'external-same-tab',
8461
- internalLinkClass: 'internal-same-tab',
8462
- },
8463
- };
8464
- this.markdownLinksProps = {
8465
- content: 'Consulta [la documentación de Angular](https://angular.io/docs) y ve a [configuración del perfil](/profile/settings) para más opciones.',
8466
- size: 'medium',
8467
- color: 'dark',
8468
- bold: false,
8469
- processLinks: true,
8470
- linkConfig: {
8471
- openExternalInNewTab: true,
8472
- openInternalInNewTab: false,
8473
- processMarkdownLinks: true,
8474
- linkClass: 'markdown-link',
8475
- externalLinkClass: 'markdown-external',
8476
- internalLinkClass: 'markdown-internal',
8477
- },
8478
- };
8479
- this.mixedFormatsProps = {
8480
- content: 'Aquí hay [documentación oficial](https://angular.io/docs), un enlace directo https://github.com/angular/angular, y una ruta interna /dashboard/analytics. ¡Todos funcionan!',
8481
- size: 'medium',
8482
- color: 'dark',
8483
- bold: false,
8484
- processLinks: true,
8485
- linkConfig: {
8486
- openExternalInNewTab: true,
8487
- openInternalInNewTab: false,
8488
- processMarkdownLinks: true,
8489
- linkClass: 'mixed-link',
8490
- externalLinkClass: 'mixed-external',
8491
- internalLinkClass: 'mixed-internal',
8492
- },
8493
- };
8494
- this.punctuationTestProps = {
8495
- content: 'URLs con puntuación final: https://ionicframework.com/docs, también https://angular.io! Pregunta sobre https://github.com/angular? Y punto final: https://typescript.org. Paréntesis (https://rxjs.dev) y comillas "https://zone.js". ¡Todos funcionan!',
8496
- size: 'medium',
8497
- color: 'dark',
8498
- bold: false,
8499
- processLinks: true,
8500
- linkConfig: {
8501
- openExternalInNewTab: true,
8502
- linkClass: 'punctuation-test',
8503
- externalLinkClass: 'external-punct',
8504
- },
8505
- };
8506
- this.complexUrlsProps = {
8507
- content: 'URLs complejas: https://example.com/path?param=value&other=123#section, búsqueda en https://google.com/search?q=angular+components, y API https://api.github.com/repos/owner/repo/issues?state=open. Todos con parámetros y fragmentos.',
8508
- size: 'medium',
8509
- color: 'dark',
8510
- bold: false,
8511
- processLinks: true,
8512
- linkConfig: {
8513
- openExternalInNewTab: true,
8514
- linkClass: 'complex-url',
8515
- externalLinkClass: 'complex-external',
8516
- },
8517
- };
8518
- }
8519
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LinkProcessingExampleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8520
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: LinkProcessingExampleComponent, isStandalone: true, selector: "val-link-processing-example", ngImport: i0, template: `
8521
- <div class="link-examples">
8522
- <h2>Ejemplos de Procesamiento de Enlaces</h2>
8523
-
8524
- <div class="example-section">
8525
- <h3>Texto sin procesamiento de enlaces:</h3>
8526
- <val-text [props]="basicTextProps"></val-text>
8527
- </div>
8528
-
8529
- <div class="example-section">
8530
- <h3>Texto con procesamiento básico de enlaces:</h3>
8531
- <val-text [props]="basicLinksProps"></val-text>
8532
- </div>
8533
-
8534
- <div class="example-section">
8535
- <h3>Enlaces con configuración personalizada:</h3>
8536
- <val-text [props]="customLinksProps"></val-text>
8537
- </div>
8538
-
8539
- <div class="example-section">
8540
- <h3>Enlaces internos y externos mezclados:</h3>
8541
- <val-text [props]="mixedLinksProps"></val-text>
8542
- </div>
8543
-
8544
- <div class="example-section">
8545
- <h3>Enlaces sin abrir en nueva pestaña:</h3>
8546
- <val-text [props]="sameTabLinksProps"></val-text>
8547
- </div>
8548
-
8549
- <div class="example-section">
8550
- <h3>Enlaces estilo Markdown [texto](url):</h3>
8551
- <val-text [props]="markdownLinksProps"></val-text>
8552
- </div>
8553
-
8554
- <div class="example-section">
8555
- <h3>Mezcla de enlaces directos y Markdown:</h3>
8556
- <val-text [props]="mixedFormatsProps"></val-text>
8557
- </div>
8558
-
8559
- <div class="example-section">
8560
- <h3>Corrección de puntuación en URLs:</h3>
8561
- <val-text [props]="punctuationTestProps"></val-text>
8562
- </div>
8563
-
8564
- <div class="example-section">
8565
- <h3>URLs complejas con parámetros y fragmentos:</h3>
8566
- <val-text [props]="complexUrlsProps"></val-text>
8567
- </div>
8568
- </div>
8569
- `, isInline: true, styles: [".example-section{margin-bottom:24px;padding:16px;border:1px solid var(--ion-color-light, #f4f5f8);border-radius:8px;background:var(--ion-color-light-tint, #f5f6f9)}h2{color:var(--ion-color-primary, #3880ff);margin-bottom:20px}h3{color:var(--ion-color-dark, #222428);margin-bottom:10px;font-size:16px}\n"], dependencies: [{ kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }] }); }
8570
- }
8571
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LinkProcessingExampleComponent, decorators: [{
8572
- type: Component,
8573
- args: [{ selector: 'val-link-processing-example', standalone: true, imports: [TextComponent], template: `
8574
- <div class="link-examples">
8575
- <h2>Ejemplos de Procesamiento de Enlaces</h2>
8576
-
8577
- <div class="example-section">
8578
- <h3>Texto sin procesamiento de enlaces:</h3>
8579
- <val-text [props]="basicTextProps"></val-text>
8580
- </div>
8581
-
8582
- <div class="example-section">
8583
- <h3>Texto con procesamiento básico de enlaces:</h3>
8584
- <val-text [props]="basicLinksProps"></val-text>
8585
- </div>
8586
-
8587
- <div class="example-section">
8588
- <h3>Enlaces con configuración personalizada:</h3>
8589
- <val-text [props]="customLinksProps"></val-text>
8590
- </div>
8591
-
8592
- <div class="example-section">
8593
- <h3>Enlaces internos y externos mezclados:</h3>
8594
- <val-text [props]="mixedLinksProps"></val-text>
8595
- </div>
8596
-
8597
- <div class="example-section">
8598
- <h3>Enlaces sin abrir en nueva pestaña:</h3>
8599
- <val-text [props]="sameTabLinksProps"></val-text>
8600
- </div>
8601
-
8602
- <div class="example-section">
8603
- <h3>Enlaces estilo Markdown [texto](url):</h3>
8604
- <val-text [props]="markdownLinksProps"></val-text>
8605
- </div>
8606
-
8607
- <div class="example-section">
8608
- <h3>Mezcla de enlaces directos y Markdown:</h3>
8609
- <val-text [props]="mixedFormatsProps"></val-text>
8610
- </div>
8611
-
8612
- <div class="example-section">
8613
- <h3>Corrección de puntuación en URLs:</h3>
8614
- <val-text [props]="punctuationTestProps"></val-text>
8615
- </div>
8616
-
8617
- <div class="example-section">
8618
- <h3>URLs complejas con parámetros y fragmentos:</h3>
8619
- <val-text [props]="complexUrlsProps"></val-text>
8620
- </div>
8621
- </div>
8622
- `, styles: [".example-section{margin-bottom:24px;padding:16px;border:1px solid var(--ion-color-light, #f4f5f8);border-radius:8px;background:var(--ion-color-light-tint, #f5f6f9)}h2{color:var(--ion-color-primary, #3880ff);margin-bottom:20px}h3{color:var(--ion-color-dark, #222428);margin-bottom:10px;font-size:16px}\n"] }]
8623
- }] });
8624
-
8625
- /**
8626
- * MultiLanguageDemoComponent - Demuestra el sistema de idiomas flexible.
8627
- *
8628
- * Este componente muestra cómo el sistema maneja múltiples idiomas,
8629
- * fallbacks automáticos y warnings por traducciones faltantes.
8630
- */
8631
- class MultiLanguageDemoComponent {
8632
- constructor(content, langService) {
8633
- this.content = content;
8634
- this.langService = langService;
8635
- this.availableLanguages = [];
8636
- this.analysisResults = null;
8637
- // Global content observables
8638
- this.okButton$ = this.content.fromContent({ key: 'ok' });
8639
- this.cancelButton$ = this.content.fromContent({ key: 'cancel' });
8640
- this.saveButton$ = this.content.fromContent({ key: 'save' });
8641
- this.deleteButton$ = this.content.fromContent({ key: 'delete' });
8642
- // Content that might have missing translations
8643
- this.nextButton$ = this.content.fromContent({ key: 'next', fallback: 'Next' });
8644
- this.finishButton$ = this.content.fromContent({ key: 'finish', fallback: 'Finish' });
8645
- this.searchPlaceholder$ = this.content.fromContent({ key: 'searchPlaceholder', fallback: 'Search...' });
8646
- this.noDataMessage$ = this.content.fromContent({ key: 'noData', fallback: 'No data available' });
8647
- }
8648
- ngOnInit() {
8649
- this.availableLanguages = this.langService.availableLangs;
8650
- }
8651
- switchLanguage(lang) {
8652
- console.log(`Switching to language: ${lang}`);
8653
- this.langService.setLang(lang);
8654
- this.analysisResults = null; // Reset analysis when language changes
8655
- }
8656
- getLanguageName(lang) {
8657
- const names = {
8658
- [LANGUAGES.ES]: 'Español',
8659
- [LANGUAGES.EN]: 'English',
8660
- [LANGUAGES.FR]: 'Français',
8661
- [LANGUAGES.DE]: 'Deutsch',
8662
- pt: 'Português',
8663
- };
8664
- return names[lang] || lang.toUpperCase();
8665
- }
8666
- analyzeCurrentComponent() {
8667
- const componentName = '_global'; // Analyzing global content for this demo
8668
- const availableLanguages = this.langService.getAvailableLanguagesForComponent(componentName);
8669
- const missingKeys = this.langService.getMissingContentKeys(componentName, this.langService.currentLang);
8670
- this.analysisResults = {
8671
- availableLanguages,
8672
- missingKeys,
8673
- };
8674
- console.log('Component analysis results:', this.analysisResults);
8675
- }
8676
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiLanguageDemoComponent, deps: [{ token: ContentService }, { token: LangService }], target: i0.ɵɵFactoryTarget.Component }); }
8677
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MultiLanguageDemoComponent, isStandalone: true, selector: "val-multi-language-demo", ngImport: i0, template: `
8678
- <div class="multi-lang-demo">
8679
- <h2>Sistema de Idiomas Flexible</h2>
8680
-
8681
- <div class="language-info">
8682
- <h3>Información del Sistema:</h3>
8683
- <p><strong>Idioma actual:</strong> {{ langService.currentLang }}</p>
8684
- <p><strong>Idioma por defecto:</strong> {{ langService.defaultLanguage }}</p>
8685
- <p><strong>Idiomas disponibles:</strong> {{ langService.availableLangs.join(', ') }}</p>
8686
- </div>
8687
-
8688
- <div class="language-switcher">
8689
- <h3>Cambiar Idioma:</h3>
8690
- <div class="button-group">
8691
- <button
8692
- *ngFor="let lang of availableLanguages"
8693
- [class.active]="lang === langService.currentLang"
8694
- (click)="switchLanguage(lang)"
8695
- >
8696
- {{ getLanguageName(lang) }}
8697
- </button>
8698
- <!-- Ejemplo de idioma no disponible -->
8699
- <button (click)="switchLanguage('pt')">Português (no disponible)</button>
8700
- </div>
8701
- </div>
8702
-
8703
- <div class="content-examples">
8704
- <h3>Contenido Global:</h3>
8705
- <div class="example-grid">
8706
- <val-text
8707
- [props]="{ content: okButton$ | async, size: 'medium', color: 'dark', bold: false, processLinks: false }"
8708
- ></val-text>
8709
- <val-text
8710
- [props]="{
8711
- content: cancelButton$ | async,
8712
- size: 'medium',
8713
- color: 'dark',
8714
- bold: false,
8715
- processLinks: false,
8716
- }"
8717
- ></val-text>
8718
- <val-text
8719
- [props]="{ content: saveButton$ | async, size: 'medium', color: 'dark', bold: false, processLinks: false }"
8720
- ></val-text>
8721
- <val-text
8722
- [props]="{
8723
- content: deleteButton$ | async,
8724
- size: 'medium',
8725
- color: 'dark',
8726
- bold: false,
8727
- processLinks: false,
8728
- }"
8729
- ></val-text>
8730
- </div>
8731
-
8732
- <h3>Contenido con Fallback (algunas traducciones faltantes):</h3>
8733
- <div class="example-grid">
8734
- <val-text
8735
- [props]="{ content: nextButton$ | async, size: 'medium', color: 'dark', bold: false, processLinks: false }"
8736
- ></val-text>
8737
- <val-text
8738
- [props]="{
8739
- content: finishButton$ | async,
8740
- size: 'medium',
8741
- color: 'dark',
8742
- bold: false,
8743
- processLinks: false,
8744
- }"
8745
- ></val-text>
8746
- <val-text
8747
- [props]="{
8748
- content: searchPlaceholder$ | async,
8749
- size: 'medium',
8750
- color: 'dark',
8751
- bold: false,
8752
- processLinks: false,
8753
- }"
8754
- ></val-text>
8755
- <val-text
8756
- [props]="{
8757
- content: noDataMessage$ | async,
8758
- size: 'medium',
8759
- color: 'dark',
8760
- bold: false,
8761
- processLinks: false,
8762
- }"
8763
- ></val-text>
8764
- </div>
8765
- </div>
8766
-
8767
- <div class="warning-info">
8768
- <h3>Información de Warnings:</h3>
8769
- <p>
8770
- Abre la consola del navegador para ver los warnings cuando cambies a idiomas con traducciones incompletas
8771
- (francés, alemán).
8772
- </p>
8773
- <p>El sistema automáticamente usará el idioma por defecto o el primer idioma disponible como fallback.</p>
8774
- </div>
8775
-
8776
- <div class="component-analysis">
8777
- <h3>Análisis del Componente:</h3>
8778
- <button (click)="analyzeCurrentComponent()">Analizar Contenido</button>
8779
- <div *ngIf="analysisResults" class="analysis-results">
8780
- <p>
8781
- <strong>Idiomas disponibles para este componente:</strong>
8782
- {{ analysisResults.availableLanguages.join(', ') }}
8783
- </p>
8784
- <div *ngIf="analysisResults.missingKeys.length > 0">
8785
- <p>
8786
- <strong>Claves faltantes en {{ langService.currentLang }}:</strong>
8787
- </p>
8788
- <ul>
8789
- <li *ngFor="let key of analysisResults.missingKeys">{{ key }}</li>
8790
- </ul>
8791
- </div>
8792
- </div>
8793
- </div>
8794
- </div>
8795
- `, isInline: true, styles: [".multi-lang-demo{padding:20px;max-width:800px}.language-info,.content-examples,.warning-info,.component-analysis{margin:20px 0;padding:15px;border:1px solid var(--ion-color-light, #f4f5f8);border-radius:8px;background:var(--ion-color-light-tint, #f5f6f9)}.button-group{display:flex;gap:10px;flex-wrap:wrap}.button-group button{padding:8px 16px;border:1px solid var(--ion-color-primary, #3880ff);background:#fff;color:var(--ion-color-primary, #3880ff);border-radius:4px;cursor:pointer;transition:all .2s}.button-group button:hover{background:var(--ion-color-primary-tint, #4992ff);color:#fff}.button-group button.active{background:var(--ion-color-primary, #3880ff);color:#fff}.example-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px;margin-top:10px}.analysis-results{margin-top:10px;padding:10px;background:#fff;border-radius:4px}h2{color:var(--ion-color-primary, #3880ff)}h3{color:var(--ion-color-dark, #222428);margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }] }); }
8796
- }
8797
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiLanguageDemoComponent, decorators: [{
8798
- type: Component,
8799
- args: [{ selector: 'val-multi-language-demo', standalone: true, imports: [CommonModule, TextComponent, ButtonComponent], template: `
8800
- <div class="multi-lang-demo">
8801
- <h2>Sistema de Idiomas Flexible</h2>
8802
-
8803
- <div class="language-info">
8804
- <h3>Información del Sistema:</h3>
8805
- <p><strong>Idioma actual:</strong> {{ langService.currentLang }}</p>
8806
- <p><strong>Idioma por defecto:</strong> {{ langService.defaultLanguage }}</p>
8807
- <p><strong>Idiomas disponibles:</strong> {{ langService.availableLangs.join(', ') }}</p>
8808
- </div>
8809
-
8810
- <div class="language-switcher">
8811
- <h3>Cambiar Idioma:</h3>
8812
- <div class="button-group">
8813
- <button
8814
- *ngFor="let lang of availableLanguages"
8815
- [class.active]="lang === langService.currentLang"
8816
- (click)="switchLanguage(lang)"
8817
- >
8818
- {{ getLanguageName(lang) }}
8819
- </button>
8820
- <!-- Ejemplo de idioma no disponible -->
8821
- <button (click)="switchLanguage('pt')">Português (no disponible)</button>
8822
- </div>
8823
- </div>
8824
-
8825
- <div class="content-examples">
8826
- <h3>Contenido Global:</h3>
8827
- <div class="example-grid">
8828
- <val-text
8829
- [props]="{ content: okButton$ | async, size: 'medium', color: 'dark', bold: false, processLinks: false }"
8830
- ></val-text>
8831
- <val-text
8832
- [props]="{
8833
- content: cancelButton$ | async,
8834
- size: 'medium',
8835
- color: 'dark',
8836
- bold: false,
8837
- processLinks: false,
8838
- }"
8839
- ></val-text>
8840
- <val-text
8841
- [props]="{ content: saveButton$ | async, size: 'medium', color: 'dark', bold: false, processLinks: false }"
8842
- ></val-text>
8843
- <val-text
8844
- [props]="{
8845
- content: deleteButton$ | async,
8846
- size: 'medium',
8847
- color: 'dark',
8848
- bold: false,
8849
- processLinks: false,
8850
- }"
8851
- ></val-text>
8852
- </div>
8853
-
8854
- <h3>Contenido con Fallback (algunas traducciones faltantes):</h3>
8855
- <div class="example-grid">
8856
- <val-text
8857
- [props]="{ content: nextButton$ | async, size: 'medium', color: 'dark', bold: false, processLinks: false }"
8858
- ></val-text>
8859
- <val-text
8860
- [props]="{
8861
- content: finishButton$ | async,
8862
- size: 'medium',
8863
- color: 'dark',
8864
- bold: false,
8865
- processLinks: false,
8866
- }"
8867
- ></val-text>
8868
- <val-text
8869
- [props]="{
8870
- content: searchPlaceholder$ | async,
8871
- size: 'medium',
8872
- color: 'dark',
8873
- bold: false,
8874
- processLinks: false,
8875
- }"
8876
- ></val-text>
8877
- <val-text
8878
- [props]="{
8879
- content: noDataMessage$ | async,
8880
- size: 'medium',
8881
- color: 'dark',
8882
- bold: false,
8883
- processLinks: false,
8884
- }"
8885
- ></val-text>
8886
- </div>
8887
- </div>
8888
-
8889
- <div class="warning-info">
8890
- <h3>Información de Warnings:</h3>
8891
- <p>
8892
- Abre la consola del navegador para ver los warnings cuando cambies a idiomas con traducciones incompletas
8893
- (francés, alemán).
8894
- </p>
8895
- <p>El sistema automáticamente usará el idioma por defecto o el primer idioma disponible como fallback.</p>
8896
- </div>
8897
-
8898
- <div class="component-analysis">
8899
- <h3>Análisis del Componente:</h3>
8900
- <button (click)="analyzeCurrentComponent()">Analizar Contenido</button>
8901
- <div *ngIf="analysisResults" class="analysis-results">
8902
- <p>
8903
- <strong>Idiomas disponibles para este componente:</strong>
8904
- {{ analysisResults.availableLanguages.join(', ') }}
8905
- </p>
8906
- <div *ngIf="analysisResults.missingKeys.length > 0">
8907
- <p>
8908
- <strong>Claves faltantes en {{ langService.currentLang }}:</strong>
8909
- </p>
8910
- <ul>
8911
- <li *ngFor="let key of analysisResults.missingKeys">{{ key }}</li>
8912
- </ul>
8913
- </div>
8914
- </div>
8915
- </div>
8916
- </div>
8917
- `, styles: [".multi-lang-demo{padding:20px;max-width:800px}.language-info,.content-examples,.warning-info,.component-analysis{margin:20px 0;padding:15px;border:1px solid var(--ion-color-light, #f4f5f8);border-radius:8px;background:var(--ion-color-light-tint, #f5f6f9)}.button-group{display:flex;gap:10px;flex-wrap:wrap}.button-group button{padding:8px 16px;border:1px solid var(--ion-color-primary, #3880ff);background:#fff;color:var(--ion-color-primary, #3880ff);border-radius:4px;cursor:pointer;transition:all .2s}.button-group button:hover{background:var(--ion-color-primary-tint, #4992ff);color:#fff}.button-group button.active{background:var(--ion-color-primary, #3880ff);color:#fff}.example-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px;margin-top:10px}.analysis-results{margin-top:10px;padding:10px;background:#fff;border-radius:4px}h2{color:var(--ion-color-primary, #3880ff)}h3{color:var(--ion-color-dark, #222428);margin-bottom:10px}\n"] }]
8918
- }], ctorParameters: () => [{ type: ContentService }, { type: LangService }] });
8919
-
8920
- /**
8921
- * Simple demo component showcasing reactive content patterns
8922
- * for buttons and alert boxes.
8923
- *
8924
- * Demonstrates:
8925
- * - Button components with reactive text
8926
- * - Alert boxes with reactive content
8927
- * - Language switching
8928
- * - Static vs reactive content patterns
8929
- */
8930
- class ReactiveComponentsDemoComponent {
8931
- constructor(contentService, langService) {
8932
- this.contentService = contentService;
8933
- this.langService = langService;
8934
- this.subscriptions = new Subscription();
8935
- }
8936
- ngOnInit() {
8937
- this.initializeContent();
8938
- this.initializeComponents();
8939
- }
8940
- ngOnDestroy() {
8941
- this.subscriptions.unsubscribe();
8942
- }
8943
- initializeContent() {
8944
- // Page-level content
8945
- this.pageTitle$ = this.contentService.fromContent({
8946
- className: 'reactiveDemo',
8947
- key: 'title',
8948
- fallback: 'Reactive Components Demo',
8949
- });
8950
- this.languageLabel$ = this.contentService.fromContent({
8951
- className: '_global',
8952
- key: 'language',
8953
- fallback: 'Language',
8954
- });
8955
- this.buttonSectionTitle$ = this.contentService.fromContent({
8956
- className: 'reactiveDemo',
8957
- key: 'buttons.title',
8958
- fallback: 'Reactive Buttons',
8959
- });
8960
- this.alertSectionTitle$ = this.contentService.fromContent({
8961
- className: 'reactiveDemo',
8962
- key: 'alerts.title',
8963
- fallback: 'Reactive Alerts',
8964
- });
8965
- // Language state
8966
- this.currentLanguage$ = this.langService.currentLang$;
8967
- this.availableLanguages$ = this.langService.currentLang$.pipe(map(() => this.langService.availableLangs));
8968
- }
8969
- initializeComponents() {
8970
- // Reactive buttons with common actions
8971
- this.saveButton = {
8972
- color: 'primary',
8973
- fill: 'solid',
8974
- type: 'button',
8975
- state: ComponentStates.ENABLED,
8976
- textConfig: {
8977
- className: '_global',
8978
- key: 'save',
8979
- fallback: 'Save',
8980
- },
8981
- handler: () => this.handleSave(),
8982
- };
8983
- this.cancelButton = {
8984
- color: 'medium',
8985
- fill: 'outline',
8986
- type: 'button',
8987
- state: ComponentStates.ENABLED,
8988
- textConfig: {
8989
- className: '_global',
8990
- key: 'cancel',
8991
- fallback: 'Cancel',
8992
- },
8993
- handler: () => this.handleCancel(),
8994
- };
8995
- // Static button for comparison
8996
- this.staticButton = {
8997
- color: 'tertiary',
8998
- fill: 'outline',
8999
- type: 'button',
9000
- state: ComponentStates.ENABLED,
9001
- text: 'Static Button', // Static text
9002
- handler: () => this.handleStatic(),
9003
- };
9004
- // Reactive alert boxes
9005
- this.warningAlert = {
9006
- box: {
9007
- color: 'warning',
9008
- rounded: true,
9009
- bordered: false,
9010
- icon: 'warning',
9011
- },
9012
- icon: {
9013
- name: 'warning',
9014
- color: 'warning',
9015
- size: 'medium',
9016
- },
9017
- textConfig: {
9018
- className: 'reactiveDemo',
9019
- key: 'alerts.warning',
9020
- fallback: 'This is a warning message',
9021
- },
9022
- textStyle: {
9023
- size: 'medium',
9024
- bold: false,
9025
- },
9026
- };
9027
- this.successAlert = {
9028
- box: {
9029
- color: 'success',
9030
- rounded: true,
9031
- bordered: false,
9032
- icon: 'checkmark-circle',
9033
- },
9034
- icon: {
9035
- name: 'checkmark-circle',
9036
- color: 'success',
9037
- size: 'medium',
9038
- },
9039
- textConfig: {
9040
- className: 'reactiveDemo',
9041
- key: 'alerts.success',
9042
- fallback: 'Operation completed successfully!',
9043
- },
9044
- textStyle: {
9045
- size: 'medium',
9046
- bold: true,
9047
- },
9048
- };
9049
- // Static alert for comparison
9050
- this.staticAlert = {
9051
- box: {
9052
- color: 'dark',
9053
- rounded: true,
9054
- bordered: false,
9055
- icon: 'information-circle',
9056
- },
9057
- icon: {
9058
- name: 'information-circle',
9059
- color: 'dark',
9060
- size: 'medium',
9061
- },
9062
- text: 'This is a static alert message', // Static text
9063
- textStyle: {
9064
- size: 'medium',
9065
- bold: false,
9066
- },
9067
- };
9068
- }
9069
- // Event handlers
9070
- changeLanguage(language) {
9071
- this.langService.setLang(language);
9072
- }
9073
- handleSave() {
9074
- console.log('Save button clicked');
9075
- }
9076
- handleCancel() {
9077
- console.log('Cancel button clicked');
9078
- }
9079
- handleStatic() {
9080
- console.log('Static button clicked');
9081
- }
9082
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReactiveComponentsDemoComponent, deps: [{ token: ContentService }, { token: LangService }], target: i0.ɵɵFactoryTarget.Component }); }
9083
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ReactiveComponentsDemoComponent, isStandalone: true, selector: "val-reactive-components-demo", ngImport: i0, template: `
9084
- <div class="reactive-components-demo">
9085
- <ion-card>
9086
- <ion-card-header>
9087
- <ion-card-title>{{ pageTitle$ | async }}</ion-card-title>
9088
- </ion-card-header>
9089
-
9090
- <ion-card-content>
9091
- <!-- Language Selector -->
9092
- <ion-item>
9093
- <ion-label>{{ languageLabel$ | async }}</ion-label>
9094
- <ion-select
9095
- interface="popover"
9096
- [value]="currentLanguage$ | async"
9097
- (ionChange)="changeLanguage($event.detail.value)"
9098
- >
9099
- <ion-select-option *ngFor="let lang of availableLanguages$ | async" [value]="lang">
9100
- {{ lang | uppercase }}
9101
- </ion-select-option>
9102
- </ion-select>
9103
- </ion-item>
9104
-
9105
- <!-- Reactive Buttons Demo -->
9106
- <div class="section">
9107
- <h3>{{ buttonSectionTitle$ | async }}</h3>
9108
-
9109
- <!-- Common action buttons with reactive text -->
9110
- <div class="button-grid">
9111
- <val-button [props]="saveButton"></val-button>
9112
- <val-button [props]="cancelButton"></val-button>
9113
- <val-button [props]="staticButton"></val-button>
9114
- </div>
9115
- </div>
9116
-
9117
- <!-- Reactive Alert Boxes Demo -->
9118
- <div class="section">
9119
- <h3>{{ alertSectionTitle$ | async }}</h3>
9120
-
9121
- <!-- Alert with reactive content -->
9122
- <val-alert-box [props]="warningAlert"></val-alert-box>
9123
- <val-alert-box [props]="successAlert"></val-alert-box>
9124
- <val-alert-box [props]="staticAlert"></val-alert-box>
9125
- </div>
9126
-
9127
- <!-- Analysis -->
9128
- <div class="section">
9129
- <h3>Analysis</h3>
9130
- <div class="analysis-info">
9131
- <p><strong>Current Language:</strong> {{ currentLanguage$ | async | uppercase }}</p>
9132
- <p><strong>Available Languages:</strong> {{ (availableLanguages$ | async)?.join(', ') | uppercase }}</p>
9133
- </div>
9134
- </div>
9135
- </ion-card-content>
9136
- </ion-card>
9137
- </div>
9138
- `, isInline: true, styles: [".reactive-components-demo{padding:16px}.section{margin:24px 0}.button-grid{display:flex;gap:12px;flex-wrap:wrap;margin:16px 0}.analysis-info{background:var(--ion-color-light);padding:16px;border-radius:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "expandedIcon", "fill", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: AlertBoxComponent, selector: "val-alert-box", inputs: ["props"] }] }); }
9139
- }
9140
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReactiveComponentsDemoComponent, decorators: [{
9141
- type: Component,
9142
- args: [{ selector: 'val-reactive-components-demo', standalone: true, imports: [
9143
- CommonModule,
9144
- IonCard,
9145
- IonCardContent,
9146
- IonCardHeader,
9147
- IonCardTitle,
9148
- IonSelect,
9149
- IonSelectOption,
9150
- IonItem,
9151
- IonLabel,
9152
- ButtonComponent,
9153
- AlertBoxComponent,
9154
- ], template: `
9155
- <div class="reactive-components-demo">
9156
- <ion-card>
9157
- <ion-card-header>
9158
- <ion-card-title>{{ pageTitle$ | async }}</ion-card-title>
9159
- </ion-card-header>
9160
-
9161
- <ion-card-content>
9162
- <!-- Language Selector -->
9163
- <ion-item>
9164
- <ion-label>{{ languageLabel$ | async }}</ion-label>
9165
- <ion-select
9166
- interface="popover"
9167
- [value]="currentLanguage$ | async"
9168
- (ionChange)="changeLanguage($event.detail.value)"
9169
- >
9170
- <ion-select-option *ngFor="let lang of availableLanguages$ | async" [value]="lang">
9171
- {{ lang | uppercase }}
9172
- </ion-select-option>
9173
- </ion-select>
9174
- </ion-item>
9175
-
9176
- <!-- Reactive Buttons Demo -->
9177
- <div class="section">
9178
- <h3>{{ buttonSectionTitle$ | async }}</h3>
9179
-
9180
- <!-- Common action buttons with reactive text -->
9181
- <div class="button-grid">
9182
- <val-button [props]="saveButton"></val-button>
9183
- <val-button [props]="cancelButton"></val-button>
9184
- <val-button [props]="staticButton"></val-button>
9185
- </div>
9186
- </div>
9187
-
9188
- <!-- Reactive Alert Boxes Demo -->
9189
- <div class="section">
9190
- <h3>{{ alertSectionTitle$ | async }}</h3>
9191
-
9192
- <!-- Alert with reactive content -->
9193
- <val-alert-box [props]="warningAlert"></val-alert-box>
9194
- <val-alert-box [props]="successAlert"></val-alert-box>
9195
- <val-alert-box [props]="staticAlert"></val-alert-box>
9196
- </div>
9197
-
9198
- <!-- Analysis -->
9199
- <div class="section">
9200
- <h3>Analysis</h3>
9201
- <div class="analysis-info">
9202
- <p><strong>Current Language:</strong> {{ currentLanguage$ | async | uppercase }}</p>
9203
- <p><strong>Available Languages:</strong> {{ (availableLanguages$ | async)?.join(', ') | uppercase }}</p>
9204
- </div>
9205
- </div>
9206
- </ion-card-content>
9207
- </ion-card>
9208
- </div>
9209
- `, styles: [".reactive-components-demo{padding:16px}.section{margin:24px 0}.button-grid{display:flex;gap:12px;flex-wrap:wrap;margin:16px 0}.analysis-info{background:var(--ion-color-light);padding:16px;border-radius:8px}\n"] }]
9210
- }], ctorParameters: () => [{ type: ContentService }, { type: LangService }] });
9211
-
9212
- /**
9213
- * Test component to diagnose reactive content behavior.
9214
- * Compares fromContent vs fromMultipleContent reactivity.
9215
- */
9216
- class ReactivityTestComponent {
9217
- constructor() {
9218
- this.contentService = inject(ContentService);
9219
- this.langService = inject(LangService);
9220
- // Observable for current language
9221
- this.currentLang$ = this.langService.currentLang$;
9222
- // Single key content observables (using fromContent)
9223
- this.singleWelcome$ = this.contentService.fromContent({
9224
- className: 'testReactivity',
9225
- key: 'welcomeMessage',
9226
- fallback: 'Welcome',
9227
- });
9228
- this.singleSave$ = this.contentService.fromContent({
9229
- className: 'testReactivity',
9230
- key: 'saveButton',
9231
- fallback: 'Save',
9232
- });
9233
- this.singleCancel$ = this.contentService.fromContent({
9234
- className: 'testReactivity',
9235
- key: 'cancelButton',
9236
- fallback: 'Cancel',
9237
- });
9238
- // Multiple keys content observable (using fromMultipleContent)
9239
- this.multipleContent$ = this.contentService.fromMultipleContent('testReactivity', [
9240
- 'welcomeMessage',
9241
- 'saveButton',
9242
- 'cancelButton',
9243
- ]);
9244
- // Direct LangService tests
9245
- this.directSingle$ = this.langService.getContent('testReactivity', 'welcomeMessage', 'Welcome');
9246
- this.directMultiple$ = this.langService.getMultipleContent('testReactivity', ['welcomeMessage']);
9247
- // Update counters
9248
- this.singleUpdateCount = 0;
9249
- this.multipleUpdateCount = 0;
9250
- this.directSingleUpdateCount = 0;
9251
- this.directMultipleUpdateCount = 0;
9252
- }
9253
- ngOnInit() {
9254
- // Subscribe to observables to count updates
9255
- this.singleWelcome$.subscribe(() => {
9256
- this.singleUpdateCount++;
9257
- console.log('Single key updated:', this.singleUpdateCount);
9258
- });
9259
- this.multipleContent$.subscribe(() => {
9260
- this.multipleUpdateCount++;
9261
- console.log('Multiple keys updated:', this.multipleUpdateCount);
9262
- });
9263
- this.directSingle$.subscribe(() => {
9264
- this.directSingleUpdateCount++;
9265
- console.log('Direct single updated:', this.directSingleUpdateCount);
9266
- });
9267
- this.directMultiple$.subscribe(() => {
9268
- this.directMultipleUpdateCount++;
9269
- console.log('Direct multiple updated:', this.directMultipleUpdateCount);
9270
- });
9271
- }
9272
- switchToSpanish() {
9273
- this.langService.setLang('es');
9274
- }
9275
- switchToEnglish() {
9276
- this.langService.setLang('en');
9277
- }
9278
- switchToFrench() {
9279
- this.langService.setLang('fr');
9280
- }
9281
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReactivityTestComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9282
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ReactivityTestComponent, isStandalone: true, selector: "val-reactivity-test", ngImport: i0, template: `
9283
- <div style="padding: 20px; border: 1px solid #ccc; margin: 10px;">
9284
- <h3>Reactivity Test Component</h3>
9285
-
9286
- <!-- Current Language -->
9287
- <div style="margin-bottom: 20px;"><strong>Current Language:</strong> {{ currentLang$ | async }}</div>
9288
-
9289
- <!-- Language Switch Buttons -->
9290
- <div style="margin-bottom: 20px;">
9291
- <button (click)="switchToSpanish()" style="margin-right: 10px;">Switch to ES</button>
9292
- <button (click)="switchToEnglish()" style="margin-right: 10px;">Switch to EN</button>
9293
- <button (click)="switchToFrench()">Switch to FR</button>
9294
- </div>
9295
-
9296
- <!-- Single Key Tests -->
9297
- <div style="margin-bottom: 20px;">
9298
- <h4>Single Key Tests (fromContent)</h4>
9299
- <div><strong>welcomeMessage (fromContent):</strong> {{ singleWelcome$ | async }}</div>
9300
- <div><strong>saveButton (fromContent):</strong> {{ singleSave$ | async }}</div>
9301
- <div><strong>cancelButton (fromContent):</strong> {{ singleCancel$ | async }}</div>
9302
- </div>
9303
-
9304
- <!-- Multiple Keys Test -->
9305
- <div style="margin-bottom: 20px;">
9306
- <h4>Multiple Keys Test (fromMultipleContent)</h4>
9307
- <div>
9308
- <strong>welcomeMessage (multiple):</strong>
9309
- {{ (multipleContent$ | async)?.['welcomeMessage'] || 'Loading...' }}
9310
- </div>
9311
- <div>
9312
- <strong>saveButton (multiple):</strong> {{ (multipleContent$ | async)?.['saveButton'] || 'Loading...' }}
9313
- </div>
9314
- <div>
9315
- <strong>cancelButton (multiple):</strong> {{ (multipleContent$ | async)?.['cancelButton'] || 'Loading...' }}
9316
- </div>
9317
- </div>
9318
-
9319
- <!-- Direct LangService Tests -->
9320
- <div style="margin-bottom: 20px;">
9321
- <h4>Direct LangService Tests</h4>
9322
- <div><strong>welcomeMessage (direct single):</strong> {{ directSingle$ | async }}</div>
9323
- <div>
9324
- <strong>welcomeMessage (direct multiple):</strong>
9325
- {{ (directMultiple$ | async)?.['welcomeMessage'] || 'Loading...' }}
9326
- </div>
9327
- </div>
9328
-
9329
- <!-- Update Counter -->
9330
- <div>
9331
- <h4>Update Counters</h4>
9332
- <div><strong>Single key updates:</strong> {{ singleUpdateCount }}</div>
9333
- <div><strong>Multiple keys updates:</strong> {{ multipleUpdateCount }}</div>
9334
- <div><strong>Direct single updates:</strong> {{ directSingleUpdateCount }}</div>
9335
- <div><strong>Direct multiple updates:</strong> {{ directMultipleUpdateCount }}</div>
9336
- </div>
9337
- </div>
9338
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] }); }
9339
- }
9340
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReactivityTestComponent, decorators: [{
9341
- type: Component,
9342
- args: [{
9343
- selector: 'val-reactivity-test',
9344
- standalone: true,
9345
- imports: [CommonModule],
9346
- template: `
9347
- <div style="padding: 20px; border: 1px solid #ccc; margin: 10px;">
9348
- <h3>Reactivity Test Component</h3>
9349
-
9350
- <!-- Current Language -->
9351
- <div style="margin-bottom: 20px;"><strong>Current Language:</strong> {{ currentLang$ | async }}</div>
9352
-
9353
- <!-- Language Switch Buttons -->
9354
- <div style="margin-bottom: 20px;">
9355
- <button (click)="switchToSpanish()" style="margin-right: 10px;">Switch to ES</button>
9356
- <button (click)="switchToEnglish()" style="margin-right: 10px;">Switch to EN</button>
9357
- <button (click)="switchToFrench()">Switch to FR</button>
9358
- </div>
9359
-
9360
- <!-- Single Key Tests -->
9361
- <div style="margin-bottom: 20px;">
9362
- <h4>Single Key Tests (fromContent)</h4>
9363
- <div><strong>welcomeMessage (fromContent):</strong> {{ singleWelcome$ | async }}</div>
9364
- <div><strong>saveButton (fromContent):</strong> {{ singleSave$ | async }}</div>
9365
- <div><strong>cancelButton (fromContent):</strong> {{ singleCancel$ | async }}</div>
9366
- </div>
9367
-
9368
- <!-- Multiple Keys Test -->
9369
- <div style="margin-bottom: 20px;">
9370
- <h4>Multiple Keys Test (fromMultipleContent)</h4>
9371
- <div>
9372
- <strong>welcomeMessage (multiple):</strong>
9373
- {{ (multipleContent$ | async)?.['welcomeMessage'] || 'Loading...' }}
9374
- </div>
9375
- <div>
9376
- <strong>saveButton (multiple):</strong> {{ (multipleContent$ | async)?.['saveButton'] || 'Loading...' }}
9377
- </div>
9378
- <div>
9379
- <strong>cancelButton (multiple):</strong> {{ (multipleContent$ | async)?.['cancelButton'] || 'Loading...' }}
9380
- </div>
9381
- </div>
9382
-
9383
- <!-- Direct LangService Tests -->
9384
- <div style="margin-bottom: 20px;">
9385
- <h4>Direct LangService Tests</h4>
9386
- <div><strong>welcomeMessage (direct single):</strong> {{ directSingle$ | async }}</div>
9387
- <div>
9388
- <strong>welcomeMessage (direct multiple):</strong>
9389
- {{ (directMultiple$ | async)?.['welcomeMessage'] || 'Loading...' }}
9390
- </div>
9391
- </div>
9392
-
9393
- <!-- Update Counter -->
9394
- <div>
9395
- <h4>Update Counters</h4>
9396
- <div><strong>Single key updates:</strong> {{ singleUpdateCount }}</div>
9397
- <div><strong>Multiple keys updates:</strong> {{ multipleUpdateCount }}</div>
9398
- <div><strong>Direct single updates:</strong> {{ directSingleUpdateCount }}</div>
9399
- <div><strong>Direct multiple updates:</strong> {{ directMultipleUpdateCount }}</div>
9400
- </div>
9401
- </div>
9402
- `,
9403
- }]
9404
- }] });
9405
-
9406
- /**
9407
- * Ejemplo de uso de los componentes popover-selector y language-selector
9408
- */
9409
- class SelectorExamplesComponent {
9410
- constructor() {
9411
- // ✅ Ejemplos de Popover Selector Genérico
9412
- this.categorySelector = {
9413
- options: [
9414
- { value: 'work', label: 'Trabajo', icon: 'briefcase' },
9415
- { value: 'personal', label: 'Personal', icon: 'person' },
9416
- { value: 'travel', label: 'Viajes', icon: 'airplane' },
9417
- { value: 'health', label: 'Salud', icon: 'fitness' },
9418
- ],
9419
- selectedValue: 'work',
9420
- label: 'Categoría',
9421
- icon: 'folder',
9422
- color: 'primary',
9423
- size: 'default',
9424
- fill: 'outline',
9425
- };
9426
- this.prioritySelector = {
9427
- options: [
9428
- { value: 'low', label: 'Baja', icon: 'arrow-down', disabled: false },
9429
- { value: 'medium', label: 'Media', icon: 'remove' },
9430
- { value: 'high', label: 'Alta', icon: 'arrow-up' },
9431
- { value: 'urgent', label: 'Urgente', icon: 'warning' },
9432
- ],
9433
- selectedValue: 'medium',
9434
- label: 'Prioridad',
9435
- icon: 'flag',
9436
- color: 'warning',
9437
- size: 'large',
9438
- fill: 'solid',
9439
- shape: 'round',
9440
- };
9441
- this.multipleSelector = {
9442
- options: [
9443
- { value: 'email', label: 'Email', icon: 'mail' },
9444
- { value: 'sms', label: 'SMS', icon: 'chatbox' },
9445
- { value: 'push', label: 'Push', icon: 'notifications' },
9446
- { value: 'in-app', label: 'In-App', icon: 'apps' },
9447
- ],
9448
- selectedValue: ['email', 'push'],
9449
- label: 'Notificaciones',
9450
- icon: 'notifications-circle',
9451
- multiple: true,
9452
- color: 'tertiary',
9453
- size: 'default',
9454
- fill: 'outline',
9455
- showCheckmark: true,
9456
- };
9457
- // ✅ Ejemplos de Language Selector (con soporte multiidioma)
9458
- // Los nombres de idiomas se obtienen automáticamente del sistema de contenido
9459
- // y se muestran traducidos según el idioma actual de la aplicación
9460
- this.basicLanguageSelector = {
9461
- showLabel: true,
9462
- label: 'Idioma',
9463
- color: 'medium',
9464
- size: 'default',
9465
- fill: 'outline',
9466
- };
9467
- // Con banderas y nombres traducidos automáticamente
9468
- this.flagLanguageSelector = {
9469
- showLabel: true,
9470
- label: 'Language / Idioma',
9471
- showFlags: true,
9472
- color: 'primary',
9473
- size: 'large',
9474
- fill: 'solid',
9475
- };
9476
- // Con nombres personalizados (sobrescribe las traducciones automáticas)
9477
- this.customLanguageSelector = {
9478
- showLabel: true,
9479
- labelConfig: {
9480
- className: '_global',
9481
- key: 'language',
9482
- fallback: 'Idioma',
9483
- },
9484
- showFlags: true,
9485
- color: 'secondary',
9486
- size: 'default',
9487
- fill: 'outline',
9488
- shape: 'round',
9489
- customLanguageNames: {
9490
- es: 'Español (España)',
9491
- en: 'English (US)',
9492
- fr: 'Français',
9493
- de: 'Deutsch',
9494
- },
9495
- };
9496
- // Compacto sin etiqueta, solo banderas y nombres traducidos
9497
- this.compactLanguageSelector = {
9498
- showLabel: false,
9499
- showFlags: true,
9500
- color: 'tertiary',
9501
- size: 'small',
9502
- fill: 'clear',
9503
- };
9504
- }
9505
- // ✅ Event Handlers
9506
- onCategoryChange(category) {
9507
- console.log('Category changed:', category);
9508
- }
9509
- onPriorityChange(priority) {
9510
- console.log('Priority changed:', priority);
9511
- }
9512
- onMultipleChange(notifications) {
9513
- console.log('Notifications changed:', notifications);
9514
- }
9515
- onLanguageChange(language) {
9516
- console.log('Language changed to:', language);
9517
- // La aplicación automáticamente actualizará todos los nombres de idiomas
9518
- // según la nueva configuración de idioma seleccionada
9519
- }
9520
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectorExamplesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9521
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SelectorExamplesComponent, isStandalone: true, selector: "app-selector-examples", ngImport: i0, template: `
9522
- <div class="selector-examples">
9523
- <h2>Ejemplos de Selectores</h2>
9524
-
9525
- <!-- Popover Selector Genérico -->
9526
- <div class="section">
9527
- <h3>Popover Selector Genérico</h3>
9528
-
9529
- <div class="example-group">
9530
- <h4>Selector de Categorías:</h4>
9531
- <val-popover-selector [props]="categorySelector" (selectionChange)="onCategoryChange($event)">
9532
- </val-popover-selector>
9533
- </div>
9534
-
9535
- <div class="example-group">
9536
- <h4>Selector de Prioridad:</h4>
9537
- <val-popover-selector [props]="prioritySelector" (selectionChange)="onPriorityChange($event)">
9538
- </val-popover-selector>
9539
- </div>
9540
-
9541
- <div class="example-group">
9542
- <h4>Selector Múltiple:</h4>
9543
- <val-popover-selector [props]="multipleSelector" (selectionChange)="onMultipleChange($event)">
9544
- </val-popover-selector>
9545
- </div>
9546
- </div>
9547
-
9548
- <!-- Language Selector -->
9549
- <div class="section">
9550
- <h3>Selector de Idioma (Multiidioma)</h3>
9551
- <p>Los nombres de idiomas se muestran traducidos según el idioma actual:</p>
9552
-
9553
- <div class="example-group">
9554
- <h4>Selector Básico (nombres traducidos):</h4>
9555
- <val-language-selector [props]="basicLanguageSelector"> </val-language-selector>
9556
- </div>
9557
-
9558
- <div class="example-group">
9559
- <h4>Selector con Banderas (nombres traducidos):</h4>
9560
- <val-language-selector [props]="flagLanguageSelector"> </val-language-selector>
9561
- </div>
9562
-
9563
- <div class="example-group">
9564
- <h4>Selector Personalizado (nombres propios):</h4>
9565
- <val-language-selector [props]="customLanguageSelector" (languageChange)="onLanguageChange($event)">
9566
- </val-language-selector>
9567
- </div>
9568
-
9569
- <div class="example-group">
9570
- <h4>Selector Compacto:</h4>
9571
- <val-language-selector [props]="compactLanguageSelector"> </val-language-selector>
9572
- </div>
9573
- </div>
9574
- </div>
9575
- `, isInline: true, styles: [".selector-examples{padding:20px;max-width:800px;margin:0 auto}.section{margin:30px 0;padding:20px;border:1px solid var(--ion-color-light);border-radius:8px;background:var(--ion-color-step-50)}.section h3{margin:0 0 20px;color:var(--ion-color-primary)}.example-group{margin:20px 0;padding:15px;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.example-group h4{margin:0 0 15px;color:var(--ion-color-medium)}\n"], dependencies: [{ kind: "component", type: PopoverSelectorComponent, selector: "val-popover-selector", inputs: ["props"], outputs: ["selectionChange"] }, { kind: "component", type: LanguageSelectorComponent, selector: "val-language-selector", inputs: ["props"], outputs: ["languageChange"] }] }); }
9576
- }
9577
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectorExamplesComponent, decorators: [{
9578
- type: Component,
9579
- args: [{ selector: 'app-selector-examples', standalone: true, imports: [PopoverSelectorComponent, LanguageSelectorComponent], template: `
9580
- <div class="selector-examples">
9581
- <h2>Ejemplos de Selectores</h2>
9582
-
9583
- <!-- Popover Selector Genérico -->
9584
- <div class="section">
9585
- <h3>Popover Selector Genérico</h3>
9586
-
9587
- <div class="example-group">
9588
- <h4>Selector de Categorías:</h4>
9589
- <val-popover-selector [props]="categorySelector" (selectionChange)="onCategoryChange($event)">
9590
- </val-popover-selector>
9591
- </div>
9592
-
9593
- <div class="example-group">
9594
- <h4>Selector de Prioridad:</h4>
9595
- <val-popover-selector [props]="prioritySelector" (selectionChange)="onPriorityChange($event)">
9596
- </val-popover-selector>
9597
- </div>
9598
-
9599
- <div class="example-group">
9600
- <h4>Selector Múltiple:</h4>
9601
- <val-popover-selector [props]="multipleSelector" (selectionChange)="onMultipleChange($event)">
9602
- </val-popover-selector>
9603
- </div>
9604
- </div>
9605
-
9606
- <!-- Language Selector -->
9607
- <div class="section">
9608
- <h3>Selector de Idioma (Multiidioma)</h3>
9609
- <p>Los nombres de idiomas se muestran traducidos según el idioma actual:</p>
9610
-
9611
- <div class="example-group">
9612
- <h4>Selector Básico (nombres traducidos):</h4>
9613
- <val-language-selector [props]="basicLanguageSelector"> </val-language-selector>
9614
- </div>
9615
-
9616
- <div class="example-group">
9617
- <h4>Selector con Banderas (nombres traducidos):</h4>
9618
- <val-language-selector [props]="flagLanguageSelector"> </val-language-selector>
9619
- </div>
9620
-
9621
- <div class="example-group">
9622
- <h4>Selector Personalizado (nombres propios):</h4>
9623
- <val-language-selector [props]="customLanguageSelector" (languageChange)="onLanguageChange($event)">
9624
- </val-language-selector>
9625
- </div>
9626
-
9627
- <div class="example-group">
9628
- <h4>Selector Compacto:</h4>
9629
- <val-language-selector [props]="compactLanguageSelector"> </val-language-selector>
9630
- </div>
9631
- </div>
9632
- </div>
9633
- `, styles: [".selector-examples{padding:20px;max-width:800px;margin:0 auto}.section{margin:30px 0;padding:20px;border:1px solid var(--ion-color-light);border-radius:8px;background:var(--ion-color-step-50)}.section h3{margin:0 0 20px;color:var(--ion-color-primary)}.example-group{margin:20px 0;padding:15px;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.example-group h4{margin:0 0 15px;color:var(--ion-color-medium)}\n"] }]
9634
- }] });
9635
-
9636
- const text = {
9637
- es: {
9638
- spanish: 'Español',
9639
- english: 'Inglés',
9640
- },
9641
- en: {
9642
- spanish: 'Spanish',
9643
- english: 'English',
9644
- },
9645
- };
9646
- var LangSettings = new TextContent(text);
9647
-
9648
- /**
9649
- * Global content that can be used across all components.
9650
- * These are common texts like buttons, actions, states, etc.
9651
- * Structure: {es: {key1: 'value1', key2: 'value2'}, en: {key1: 'value1', key2: 'value2'}, fr: {...}}
9652
- *
9653
- * Note: You can add any language code. The system will automatically detect available languages
9654
- * and provide intelligent fallbacks with warnings for missing translations.
7293
+ * Global content that can be used across all components.
7294
+ * These are common texts like buttons, actions, states, etc.
7295
+ * Structure: {es: {key1: 'value1', key2: 'value2'}, en: {key1: 'value1', key2: 'value2'}, fr: {...}}
7296
+ *
7297
+ * Note: You can add any language code. The system will automatically detect available languages
7298
+ * and provide intelligent fallbacks with warnings for missing translations.
9655
7299
  */
9656
7300
  const globalContentData = {
9657
7301
  es: {
@@ -9748,60 +7392,6 @@ const globalContentData = {
9748
7392
  // Common placeholders
9749
7393
  searchPlaceholder: 'Search...',
9750
7394
  },
9751
- fr: {
9752
- // Common buttons - Example of partial translation (missing some keys intentionally)
9753
- ok: 'OK',
9754
- cancel: 'Annuler',
9755
- save: 'Sauvegarder',
9756
- delete: 'Supprimer',
9757
- edit: 'Modifier',
9758
- close: 'Fermer',
9759
- back: 'Retour',
9760
- // Common states and messages (intentionally incomplete to show fallback behavior)
9761
- loading: 'Chargement...',
9762
- error: 'Erreur',
9763
- success: 'Succès',
9764
- // Common confirmations
9765
- areYouSure: 'Êtes-vous sûr?',
9766
- // Language names (translated) - flat keys for type compatibility
9767
- languageName_es: 'Espagnol',
9768
- languageName_en: 'Anglais',
9769
- languageName_fr: 'Français',
9770
- languageName_de: 'Allemand',
9771
- languageName_pt: 'Portugais',
9772
- languageName_it: 'Italien',
9773
- languageName_zh: 'Chinois',
9774
- languageName_ja: 'Japonais',
9775
- languageName_ko: 'Coréen',
9776
- languageName_ru: 'Russe',
9777
- languageName_ar: 'Arabe',
9778
- language: 'Langue',
9779
- },
9780
- de: {
9781
- // Common buttons - Another example of partial translation
9782
- ok: 'OK',
9783
- cancel: 'Abbrechen',
9784
- save: 'Speichern',
9785
- delete: 'Löschen',
9786
- // Common states and messages
9787
- loading: 'Laden...',
9788
- error: 'Fehler',
9789
- // Common confirmations
9790
- areYouSure: 'Sind Sie sicher?',
9791
- // Language names (translated) - flat keys for type compatibility
9792
- languageName_es: 'Spanisch',
9793
- languageName_en: 'Englisch',
9794
- languageName_fr: 'Französisch',
9795
- languageName_de: 'Deutsch',
9796
- languageName_pt: 'Portugiesisch',
9797
- languageName_it: 'Italienisch',
9798
- languageName_zh: 'Chinesisch',
9799
- languageName_ja: 'Japanisch',
9800
- languageName_ko: 'Koreanisch',
9801
- languageName_ru: 'Russisch',
9802
- languageName_ar: 'Arabisch',
9803
- language: 'Sprache',
9804
- },
9805
7395
  };
9806
7396
  const GlobalContent = new TextContent(globalContentData);
9807
7397
  const content = {
@@ -9881,5 +7471,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
9881
7471
  * Generated bundle index. Do not edit.
9882
7472
  */
9883
7473
 
9884
- export { ActionType, AlertBoxComponent, AvatarComponent, BannerComponent, BaseDefault, BoxComponent, ButtonComponent, ButtonGroupComponent, CardComponent, CardSection, CardType, CheckInputComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CommentInputComponent, ComponentContentHelper, ComponentStates, ComprehensiveLinkTestComponent, ContentLoaderComponent, ContentService, CustomContentDemoComponent, DateInputComponent, DisplayComponent, DisplayDemoComponent, DisplayExampleComponent, DividerComponent, DownloadService, EmailInputComponent, ExpandableTextComponent, FileInputComponent, FooterComponent, FormComponent, FormFooterComponent, GlobalContent, HeaderComponent, HintComponent, HourInputComponent, HrefComponent, Icon, IconComponent, IconService, ImageComponent, InAppBrowserService, InputType, ItemListComponent, LANGUAGES, LangService, LanguageSelectorComponent, LayeredCardComponent, LayoutComponent, LinkComponent, LinkProcessingExampleComponent, LinkProcessorService, LinksCakeComponent, ListContentHelper, LocalStorageService, MOTION, MultiLanguageDemoComponent, NavigationService, NoContentComponent, NotesBoxComponent, NumberInputComponent, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PasswordInputComponent, PinInputComponent, PopoverSelectorComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProgressBarComponent, ProgressStatusComponent, PrompterComponent, RadioInputComponent, ReactiveComponentsDemoComponent, ReactivityTestComponent, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SelectSearchComponent, SelectorExamplesComponent, SimpleComponent, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, TextComponent, TextContent, TextInputComponent, ThemeOption, ThemeService, TitleBlockComponent, TitleComponent, ToastService, ToolbarActionType, ToolbarComponent, ValtechConfigService, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, content, createComponentContentHelper, createContentHelper, createReactiveProps, createTextProps, createTitleProps, fromContent, fromContentWithInterpolation, fromMultipleContent, globalContentData, goToTop, interpolateContent, isAtEnd, maxLength, replaceSpecialChars, resolveColor, resolveInputDefaultValue, shouldUseReactiveContent };
7474
+ export { ActionType, AlertBoxComponent, AvatarComponent, BannerComponent, BaseDefault, BoxComponent, ButtonComponent, ButtonGroupComponent, CardComponent, CardSection, CardType, CheckInputComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CommentInputComponent, ComponentContentHelper, ComponentStates, ContentLoaderComponent, ContentService, DateInputComponent, DisplayComponent, DividerComponent, DownloadService, EmailInputComponent, ExpandableTextComponent, FileInputComponent, FooterComponent, FormComponent, FormFooterComponent, GlobalContent, HeaderComponent, HintComponent, HourInputComponent, HrefComponent, Icon, IconComponent, IconService, ImageComponent, InAppBrowserService, InputType, ItemListComponent, LANGUAGES, LangService, LanguageSelectorComponent, LayeredCardComponent, LayoutComponent, LinkComponent, LinkProcessorService, LinksCakeComponent, ListContentHelper, LocalStorageService, MOTION, NavigationService, NoContentComponent, NotesBoxComponent, NumberInputComponent, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PasswordInputComponent, PinInputComponent, PopoverSelectorComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProgressBarComponent, ProgressStatusComponent, PrompterComponent, RadioInputComponent, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SelectSearchComponent, SimpleComponent, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, TextComponent, TextContent, TextInputComponent, ThemeOption, ThemeService, TitleBlockComponent, TitleComponent, ToastService, ToolbarActionType, ToolbarComponent, ValtechConfigService, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, content, createButtonProps, createComponentContentHelper, createContentHelper, createReactiveProps, createTextProps, createTitleProps, fromContent, fromContentWithInterpolation, fromMultipleContent, globalContentData, goToTop, interpolateContent, isAtEnd, maxLength, replaceSpecialChars, resolveColor, resolveInputDefaultValue, shouldUseReactiveContent };
9885
7475
  //# sourceMappingURL=valtech-components.mjs.map