valtech-components 4.0.4 → 4.0.6

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 (57) hide show
  1. package/esm2022/lib/components/atoms/button/button.component.mjs +15 -5
  2. package/esm2022/lib/components/atoms/fab/fab.component.mjs +8 -18
  3. package/esm2022/lib/components/atoms/horizontal-scroll/horizontal-scroll.component.mjs +5 -7
  4. package/esm2022/lib/components/atoms/progress-bar/progress-bar.component.mjs +3 -1
  5. package/esm2022/lib/components/atoms/progress-bar/types.mjs +1 -1
  6. package/esm2022/lib/components/molecules/accordion/accordion.component.mjs +4 -6
  7. package/esm2022/lib/components/molecules/action-card/action-card.component.mjs +5 -5
  8. package/esm2022/lib/components/molecules/breadcrumb/breadcrumb.component.mjs +5 -5
  9. package/esm2022/lib/components/molecules/card/card.component.mjs +19 -9
  10. package/esm2022/lib/components/molecules/chip-group/chip-group.component.mjs +21 -13
  11. package/esm2022/lib/components/molecules/code-display/code-display.component.mjs +5 -5
  12. package/esm2022/lib/components/molecules/comment/comment.component.mjs +29 -56
  13. package/esm2022/lib/components/molecules/content-loader/content-loader.component.mjs +13 -3
  14. package/esm2022/lib/components/molecules/date-picker/date-picker.component.mjs +7 -15
  15. package/esm2022/lib/components/molecules/date-range-input/date-range-input.component.mjs +6 -10
  16. package/esm2022/lib/components/molecules/docs-code-example/docs-code-example.component.mjs +13 -5
  17. package/esm2022/lib/components/molecules/docs-nav-links/docs-nav-links.component.mjs +7 -13
  18. package/esm2022/lib/components/molecules/docs-search/docs-search.component.mjs +12 -28
  19. package/esm2022/lib/components/molecules/features-list/features-list.component.mjs +5 -5
  20. package/esm2022/lib/components/molecules/feedback-form/feedback-form.component.mjs +5 -5
  21. package/esm2022/lib/components/molecules/file-input/file-input.component.mjs +9 -3
  22. package/esm2022/lib/components/molecules/glow-card/glow-card.component.mjs +17 -15
  23. package/esm2022/lib/components/molecules/language-selector/language-selector.component.mjs +7 -5
  24. package/esm2022/lib/components/molecules/link/link.component.mjs +3 -3
  25. package/esm2022/lib/components/molecules/media-object/media-object.component.mjs +3 -3
  26. package/esm2022/lib/components/molecules/metric-card/metric-card.component.mjs +5 -3
  27. package/esm2022/lib/components/molecules/password-input/password-input.component.mjs +11 -3
  28. package/esm2022/lib/components/molecules/pill/pill.component.mjs +7 -7
  29. package/esm2022/lib/components/molecules/popover-selector/popover-selector.component.mjs +7 -7
  30. package/esm2022/lib/components/molecules/segment-control/segment-control.component.mjs +3 -3
  31. package/esm2022/lib/components/molecules/select-search/select-search.component.mjs +15 -3
  32. package/esm2022/lib/components/molecules/share-buttons/share-buttons.component.mjs +3 -1
  33. package/esm2022/lib/components/molecules/stats-card/stats-card.component.mjs +5 -5
  34. package/esm2022/lib/components/molecules/stepper/stepper.component.mjs +11 -13
  35. package/esm2022/lib/components/molecules/tabs/tabs.component.mjs +4 -6
  36. package/esm2022/lib/components/molecules/ticket-card/ticket-card.component.mjs +3 -3
  37. package/esm2022/lib/components/organisms/banner/types.mjs +1 -1
  38. package/esm2022/lib/components/organisms/cookie-banner/cookie-banner.component.mjs +3 -1
  39. package/esm2022/lib/components/organisms/cookie-banner/types.mjs +1 -1
  40. package/esm2022/lib/components/organisms/data-table/data-table.component.mjs +11 -7
  41. package/esm2022/lib/components/organisms/login/login.component.mjs +3 -3
  42. package/esm2022/lib/services/icons.service.mjs +3 -2
  43. package/esm2022/lib/services/page-state/page-state.i18n.mjs +19 -0
  44. package/esm2022/lib/services/page-state/page-state.mjs +101 -0
  45. package/esm2022/lib/version.mjs +2 -2
  46. package/esm2022/public-api.mjs +4 -1
  47. package/fesm2022/valtech-components.mjs +405 -279
  48. package/fesm2022/valtech-components.mjs.map +1 -1
  49. package/lib/components/atoms/progress-bar/types.d.ts +2 -0
  50. package/lib/components/organisms/banner/types.d.ts +1 -1
  51. package/lib/components/organisms/cookie-banner/types.d.ts +2 -0
  52. package/lib/services/page-state/page-state.d.ts +74 -0
  53. package/lib/services/page-state/page-state.i18n.d.ts +6 -0
  54. package/lib/version.d.ts +1 -1
  55. package/package.json +1 -1
  56. package/public-api.d.ts +1 -0
  57. package/src/lib/services/firebase/firebase-messaging-sw.js +145 -0
@@ -25,7 +25,7 @@ import { getApps, getApp, initializeApp as initializeApp$1 } from 'firebase/app'
25
25
  import * as i2$1 from '@ionic/angular/standalone';
26
26
  import { AlertController, IonAvatar, IonCard, IonIcon, IonButton, IonSpinner, IonText, IonModal, IonHeader, IonToolbar, IonContent, IonButtons, IonTitle, IonProgressBar, IonSkeletonText, IonFab, IonFabButton, IonFabList, IonLabel, IonCardContent, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCheckbox, IonRadio, IonRadioGroup, IonTextarea, IonDatetime, IonSelect, IonSelectOption, IonPopover, IonList, IonItem, IonInput, IonRange, IonSearchbar, IonSegment, IonSegmentButton, IonToggle, IonRippleEffect, IonAccordion, IonAccordionGroup, IonTabBar, IonTabButton, IonBadge, IonBreadcrumb, IonBreadcrumbs, IonChip, IonNote, IonDatetimeButton, ToastController as ToastController$1, IonCol, IonRow, IonRefresher, IonRefresherContent, IonMenuButton, IonFooter, IonListHeader, IonInfiniteScroll, IonInfiniteScrollContent, IonGrid, MenuController, IonMenu, IonMenuToggle, IonSplitPane } from '@ionic/angular/standalone';
27
27
  import { addIcons } from 'ionicons';
28
- import { addOutline, addCircleOutline, alertOutline, alertCircleOutline, arrowBackOutline, arrowForwardOutline, arrowDownOutline, settings, settingsOutline, checkmarkCircleOutline, ellipsisHorizontalOutline, notifications, notificationsOutline, openOutline, closeOutline, chatbubblesOutline, shareOutline, heart, heartOutline, home, homeOutline, eyeOffOutline, eyeOutline, scanOutline, chevronDownOutline, chevronForwardOutline, checkmarkOutline, clipboardOutline, copyOutline, filterOutline, locationOutline, calendarOutline, businessOutline, logoTwitter, logoInstagram, logoLinkedin, logoYoutube, logoTiktok, logoFacebook, logoGoogle, createOutline, trashOutline, playOutline, peopleOutline, phonePortraitOutline, refreshOutline, documentTextOutline, lockClosedOutline, informationCircleOutline, logoNpm, removeOutline, optionsOutline, personOutline, shieldCheckmarkOutline, keyOutline, desktopOutline, logOutOutline, cloudDownloadOutline, cloudOutline, gitBranchOutline, layersOutline, serverOutline, warningOutline, bulbOutline, lockOpenOutline, diamondOutline, add, close, share, create, trash, star, camera, mic, send, downloadOutline, chevronDown, language, globeOutline, checkmark, list, grid, apps, menu, search, person, helpCircle, informationCircle, documentText, mail, calendar, folder, chevronForward, ellipsisHorizontal, chevronBack, playBack, playForward, ellipse, starOutline, starHalf, heartHalf, checkmarkCircle, timeOutline, flag, trendingUp, trendingDown, remove, analytics, people, cash, cart, eye, chatbubbleOutline, thumbsUpOutline, thumbsUp, happyOutline, happy, sadOutline, sad, chevronUp, pin, pencil, callOutline, logoWhatsapp, paperPlaneOutline, mailOutline, chevronDownCircleOutline, closeCircle, alertCircle, logoApple, logoMicrosoft, linkOutline, unlinkOutline, cloudOfflineOutline, documentOutline, attachOutline, cameraOutline, closeCircleOutline, imageOutline, chevronBackOutline, sendOutline, chatbubbleEllipsesOutline, swapVerticalOutline, chevronUpOutline, searchOutline, cartOutline, chatbubble, compass, compassOutline, gridOutline, listOutline, folderOutline, documents, documentsOutline, statsChart, statsChartOutline, laptopOutline, swapHorizontalOutline, cloudUploadOutline, notificationsOffOutline, alarmOutline, chatboxEllipsesOutline, checkmarkDoneOutline, cogOutline, shareSocialOutline, helpCircleOutline, menuOutline, stopCircleOutline, videocamOffOutline } from 'ionicons/icons';
28
+ import { addOutline, addCircleOutline, alertOutline, alertCircleOutline, arrowBackOutline, arrowForwardOutline, arrowDownOutline, settings, settingsOutline, checkmarkCircleOutline, ellipsisHorizontalOutline, notifications, notificationsOutline, openOutline, closeOutline, chatbubblesOutline, shareOutline, heart, heartOutline, home, homeOutline, eyeOffOutline, eyeOutline, scanOutline, chevronDownOutline, chevronForwardOutline, checkmarkOutline, clipboardOutline, copyOutline, filterOutline, locationOutline, calendarOutline, businessOutline, logoTwitter, logoInstagram, logoLinkedin, logoYoutube, logoTiktok, logoFacebook, logoGoogle, createOutline, trashOutline, playOutline, peopleOutline, phonePortraitOutline, refreshOutline, documentTextOutline, lockClosedOutline, cloudUploadOutline, informationCircleOutline, logoNpm, removeOutline, optionsOutline, personOutline, shieldCheckmarkOutline, keyOutline, desktopOutline, logOutOutline, cloudDownloadOutline, cloudOutline, gitBranchOutline, layersOutline, serverOutline, warningOutline, bulbOutline, lockOpenOutline, diamondOutline, add, close, share, create, trash, star, camera, mic, send, downloadOutline, chevronDown, language, globeOutline, checkmark, list, grid, apps, menu, search, person, helpCircle, informationCircle, documentText, mail, calendar, folder, chevronForward, ellipsisHorizontal, chevronBack, playBack, playForward, ellipse, starOutline, starHalf, heartHalf, checkmarkCircle, timeOutline, flag, trendingUp, trendingDown, remove, analytics, people, cash, cart, eye, chatbubbleOutline, thumbsUpOutline, thumbsUp, happyOutline, happy, sadOutline, sad, chevronUp, pin, pencil, callOutline, logoWhatsapp, paperPlaneOutline, mailOutline, chevronDownCircleOutline, closeCircle, alertCircle, logoApple, logoMicrosoft, linkOutline, unlinkOutline, cloudOfflineOutline, documentOutline, attachOutline, cameraOutline, closeCircleOutline, imageOutline, chevronBackOutline, sendOutline, chatbubbleEllipsesOutline, swapVerticalOutline, chevronUpOutline, searchOutline, cartOutline, chatbubble, compass, compassOutline, gridOutline, listOutline, folderOutline, documents, documentsOutline, statsChart, statsChartOutline, laptopOutline, swapHorizontalOutline, notificationsOffOutline, alarmOutline, chatboxEllipsesOutline, checkmarkDoneOutline, cogOutline, shareSocialOutline, helpCircleOutline, menuOutline, stopCircleOutline, videocamOffOutline } from 'ionicons/icons';
29
29
  import { Browser } from '@capacitor/browser';
30
30
  import * as i1$6 from '@angular/platform-browser';
31
31
  import { DomSanitizer, Meta, Title } from '@angular/platform-browser';
@@ -56,7 +56,7 @@ import { BrowserMultiFormatReader } from '@zxing/browser';
56
56
  * Current version of valtech-components.
57
57
  * This is automatically updated during the publish process.
58
58
  */
59
- const VERSION = '4.0.4';
59
+ const VERSION = '4.0.6';
60
60
 
61
61
  // Control de estado de refresco (singleton a nivel de módulo)
62
62
  let isRefreshing = false;
@@ -10159,6 +10159,7 @@ class IconService {
10159
10159
  refreshOutline,
10160
10160
  documentTextOutline,
10161
10161
  lockClosedOutline,
10162
+ cloudUploadOutline,
10162
10163
  informationCircleOutline,
10163
10164
  logoNpm,
10164
10165
  removeOutline,
@@ -10575,8 +10576,13 @@ class ButtonComponent {
10575
10576
  [disabled]="resolvedProps.state === states.DISABLED"
10576
10577
  [ngClass]="resolvedProps.size ? [resolvedProps.size] : []"
10577
10578
  >
10578
- <ion-icon *ngIf="resolvedProps.icon" [slot]="resolvedProps.icon.slot" [name]="resolvedProps.icon.name"></ion-icon>
10579
- <ion-spinner *ngIf="resolvedProps.state === states.WORKING" name="circular"></ion-spinner>
10579
+ <ion-icon
10580
+ *ngIf="resolvedProps.icon"
10581
+ [slot]="resolvedProps.icon.slot"
10582
+ [name]="resolvedProps.icon.name"
10583
+ aria-hidden="true"
10584
+ ></ion-icon>
10585
+ <ion-spinner *ngIf="resolvedProps.state === states.WORKING" name="circular" aria-label="Cargando"></ion-spinner>
10580
10586
  <ion-text *ngIf="resolvedProps.state !== states.WORKING">{{ displayText }}</ion-text>
10581
10587
  </ion-button>
10582
10588
  `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}ion-button{font-family:var(--ion-default-font),Arial,sans-serif;min-width:6.25rem;margin:0}ion-button.small{--padding-bottom: 12px;--padding-end: 14px;--padding-start: 14px;--padding-top: 12px}ion-button.button-clear{padding:0;margin:0}ion-button ion-spinner{--color: currentColor}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { 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: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }] }); }
@@ -10599,8 +10605,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
10599
10605
  [disabled]="resolvedProps.state === states.DISABLED"
10600
10606
  [ngClass]="resolvedProps.size ? [resolvedProps.size] : []"
10601
10607
  >
10602
- <ion-icon *ngIf="resolvedProps.icon" [slot]="resolvedProps.icon.slot" [name]="resolvedProps.icon.name"></ion-icon>
10603
- <ion-spinner *ngIf="resolvedProps.state === states.WORKING" name="circular"></ion-spinner>
10608
+ <ion-icon
10609
+ *ngIf="resolvedProps.icon"
10610
+ [slot]="resolvedProps.icon.slot"
10611
+ [name]="resolvedProps.icon.name"
10612
+ aria-hidden="true"
10613
+ ></ion-icon>
10614
+ <ion-spinner *ngIf="resolvedProps.state === states.WORKING" name="circular" aria-label="Cargando"></ion-spinner>
10604
10615
  <ion-text *ngIf="resolvedProps.state !== states.WORKING">{{ displayText }}</ion-text>
10605
10616
  </ion-button>
10606
10617
  `, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}ion-button{font-family:var(--ion-default-font),Arial,sans-serif;min-width:6.25rem;margin:0}ion-button.small{--padding-bottom: 12px;--padding-end: 14px;--padding-start: 14px;--padding-top: 12px}ion-button.button-clear{padding:0;margin:0}ion-button ion-spinner{--color: currentColor}\n"] }]
@@ -11382,6 +11393,7 @@ class ProgressBarComponent {
11382
11393
  [color]="resolvedProps.color"
11383
11394
  [buffer]="resolvedProps.buffer"
11384
11395
  [type]="resolvedProps.type"
11396
+ [attr.aria-label]="resolvedProps.label || 'Progreso'"
11385
11397
  ></ion-progress-bar>
11386
11398
  `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}ion-progress-bar.rounded{border-radius:.5rem}.medium{height:.25rem}.large{height:.375rem}.xlarge{height:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: IonProgressBar, selector: "ion-progress-bar", inputs: ["buffer", "color", "mode", "reversed", "type", "value"] }] }); }
11387
11399
  }
@@ -11395,6 +11407,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
11395
11407
  [color]="resolvedProps.color"
11396
11408
  [buffer]="resolvedProps.buffer"
11397
11409
  [type]="resolvedProps.type"
11410
+ [attr.aria-label]="resolvedProps.label || 'Progreso'"
11398
11411
  ></ion-progress-bar>
11399
11412
  `, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}ion-progress-bar.rounded{border-radius:.5rem}.medium{height:.25rem}.large{height:.375rem}.xlarge{height:.5rem}\n"] }]
11400
11413
  }], propDecorators: { preset: [{
@@ -12347,9 +12360,7 @@ class FabComponent {
12347
12360
  * Explicit props take precedence over preset values.
12348
12361
  */
12349
12362
  resolveProps() {
12350
- const presetProps = this.preset
12351
- ? this.presets.get('fab', this.preset)
12352
- : {};
12363
+ const presetProps = this.preset ? this.presets.get('fab', this.preset) : {};
12353
12364
  this.resolvedProps = {
12354
12365
  ...presetProps,
12355
12366
  ...this.props,
@@ -12393,11 +12404,7 @@ class FabComponent {
12393
12404
  }
12394
12405
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12395
12406
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FabComponent, isStandalone: true, selector: "val-fab", inputs: { preset: "preset", props: "props" }, outputs: { fabClick: "fabClick", actionClick: "actionClick" }, usesOnChanges: true, ngImport: i0, template: `
12396
- <ion-fab
12397
- [vertical]="getVertical()"
12398
- [horizontal]="getHorizontal()"
12399
- [activated]="isActivated"
12400
- >
12407
+ <ion-fab [vertical]="getVertical()" [horizontal]="getHorizontal()" [activated]="isActivated">
12401
12408
  <ion-fab-button
12402
12409
  [color]="resolvedProps.color || 'primary'"
12403
12410
  [size]="resolvedProps.size"
@@ -12405,7 +12412,7 @@ class FabComponent {
12405
12412
  [translucent]="resolvedProps.translucent"
12406
12413
  (click)="onMainClick()"
12407
12414
  >
12408
- <ion-icon [name]="getMainIcon()"></ion-icon>
12415
+ <ion-icon [name]="getMainIcon()" aria-hidden="true"></ion-icon>
12409
12416
  </ion-fab-button>
12410
12417
 
12411
12418
  @if (resolvedProps.actions && resolvedProps.actions.length > 0) {
@@ -12416,7 +12423,7 @@ class FabComponent {
12416
12423
  [disabled]="action.disabled"
12417
12424
  (click)="onActionClick(action)"
12418
12425
  >
12419
- <ion-icon [name]="action.icon"></ion-icon>
12426
+ <ion-icon [name]="action.icon" aria-hidden="true"></ion-icon>
12420
12427
  </ion-fab-button>
12421
12428
  }
12422
12429
  </ion-fab-list>
@@ -12427,11 +12434,7 @@ class FabComponent {
12427
12434
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FabComponent, decorators: [{
12428
12435
  type: Component,
12429
12436
  args: [{ selector: 'val-fab', standalone: true, imports: [CommonModule, IonFab, IonFabButton, IonFabList, IonIcon, IonLabel], template: `
12430
- <ion-fab
12431
- [vertical]="getVertical()"
12432
- [horizontal]="getHorizontal()"
12433
- [activated]="isActivated"
12434
- >
12437
+ <ion-fab [vertical]="getVertical()" [horizontal]="getHorizontal()" [activated]="isActivated">
12435
12438
  <ion-fab-button
12436
12439
  [color]="resolvedProps.color || 'primary'"
12437
12440
  [size]="resolvedProps.size"
@@ -12439,7 +12442,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
12439
12442
  [translucent]="resolvedProps.translucent"
12440
12443
  (click)="onMainClick()"
12441
12444
  >
12442
- <ion-icon [name]="getMainIcon()"></ion-icon>
12445
+ <ion-icon [name]="getMainIcon()" aria-hidden="true"></ion-icon>
12443
12446
  </ion-fab-button>
12444
12447
 
12445
12448
  @if (resolvedProps.actions && resolvedProps.actions.length > 0) {
@@ -12450,7 +12453,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
12450
12453
  [disabled]="action.disabled"
12451
12454
  (click)="onActionClick(action)"
12452
12455
  >
12453
- <ion-icon [name]="action.icon"></ion-icon>
12456
+ <ion-icon [name]="action.icon" aria-hidden="true"></ion-icon>
12454
12457
  </ion-fab-button>
12455
12458
  }
12456
12459
  </ion-fab-list>
@@ -13864,13 +13867,12 @@ class HorizontalScrollComponent {
13864
13867
  [class.snap-start]="props?.snapAlign === 'start'"
13865
13868
  [class.snap-center]="props?.snapAlign === 'center'"
13866
13869
  [style.padding]="props?.padding || '0px'"
13870
+ tabindex="0"
13867
13871
  >
13868
13872
  <div class="items-wrapper" [style.gap]="props?.gap || '0px'">
13869
13873
  @for (item of items; track $index) {
13870
13874
  <div class="scroll-item">
13871
- <ng-container
13872
- *ngTemplateOutlet="itemTemplate; context: { $implicit: item, index: $index }"
13873
- ></ng-container>
13875
+ <ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item, index: $index }"></ng-container>
13874
13876
  </div>
13875
13877
  }
13876
13878
  </div>
@@ -13886,13 +13888,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13886
13888
  [class.snap-start]="props?.snapAlign === 'start'"
13887
13889
  [class.snap-center]="props?.snapAlign === 'center'"
13888
13890
  [style.padding]="props?.padding || '0px'"
13891
+ tabindex="0"
13889
13892
  >
13890
13893
  <div class="items-wrapper" [style.gap]="props?.gap || '0px'">
13891
13894
  @for (item of items; track $index) {
13892
13895
  <div class="scroll-item">
13893
- <ng-container
13894
- *ngTemplateOutlet="itemTemplate; context: { $implicit: item, index: $index }"
13895
- ></ng-container>
13896
+ <ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item, index: $index }"></ng-container>
13896
13897
  </div>
13897
13898
  }
13898
13899
  </div>
@@ -15193,9 +15194,10 @@ class CardComponent {
15193
15194
  <ng-container *ngFor="let action of resolvedProps.leftActions">
15194
15195
  <ion-button
15195
15196
  *ngIf="action.type === actionTypes.ICON"
15197
+ [attr.aria-label]="action.description"
15196
15198
  (click)="clickHandler(sections.headerLeft, action.token)"
15197
15199
  >
15198
- <ion-icon slot="icon-only" [name]="action.description" color="dark"></ion-icon>
15200
+ <ion-icon slot="icon-only" [name]="action.description" color="dark" aria-hidden="true"></ion-icon>
15199
15201
  </ion-button>
15200
15202
  <val-avatar
15201
15203
  style="margin-right: 4px; cursor: pointer"
@@ -15223,9 +15225,10 @@ class CardComponent {
15223
15225
  <ng-container *ngFor="let action of resolvedProps.rightActions">
15224
15226
  <ion-button
15225
15227
  *ngIf="action.type === actionTypes.ICON"
15228
+ [attr.aria-label]="action.description"
15226
15229
  (click)="clickHandler(sections.headerRight, action.token)"
15227
15230
  >
15228
- <ion-icon slot="icon-only" [name]="action.description" color="dark"></ion-icon>
15231
+ <ion-icon slot="icon-only" [name]="action.description" color="dark" aria-hidden="true"></ion-icon>
15229
15232
  </ion-button>
15230
15233
  <val-avatar
15231
15234
  style="margin-right: 4px; cursor: pointer"
@@ -15267,7 +15270,9 @@ class CardComponent {
15267
15270
  @if (resolvedProps.image) {
15268
15271
  <img [alt]="resolvedProps.title || 'Card image'" [src]="resolvedProps.image" />
15269
15272
  }
15270
- <ion-card-content *ngIf="resolvedProps.content" class="complex-content">{{ resolvedProps.content }}</ion-card-content>
15273
+ <ion-card-content *ngIf="resolvedProps.content" class="complex-content">{{
15274
+ resolvedProps.content
15275
+ }}</ion-card-content>
15271
15276
  </div>
15272
15277
  @if (resolvedProps.footerActions && resolvedProps.footerActions.length > 0) {
15273
15278
  <div class="card-actions">
@@ -15285,9 +15290,10 @@ class CardComponent {
15285
15290
  <ng-container *ngFor="let action of resolvedProps.footerComplexActions">
15286
15291
  <ion-button
15287
15292
  *ngIf="action.type === actionTypes.ICON"
15293
+ [attr.aria-label]="action.description"
15288
15294
  (click)="clickHandler(sections.footerExtra, action.token)"
15289
15295
  >
15290
- <ion-icon slot="icon-only" [name]="action.description" color="dark"></ion-icon>
15296
+ <ion-icon slot="icon-only" [name]="action.description" color="dark" aria-hidden="true"></ion-icon>
15291
15297
  </ion-button>
15292
15298
  <val-avatar
15293
15299
  style="margin-right: 4px; cursor: pointer"
@@ -15403,9 +15409,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
15403
15409
  <ng-container *ngFor="let action of resolvedProps.leftActions">
15404
15410
  <ion-button
15405
15411
  *ngIf="action.type === actionTypes.ICON"
15412
+ [attr.aria-label]="action.description"
15406
15413
  (click)="clickHandler(sections.headerLeft, action.token)"
15407
15414
  >
15408
- <ion-icon slot="icon-only" [name]="action.description" color="dark"></ion-icon>
15415
+ <ion-icon slot="icon-only" [name]="action.description" color="dark" aria-hidden="true"></ion-icon>
15409
15416
  </ion-button>
15410
15417
  <val-avatar
15411
15418
  style="margin-right: 4px; cursor: pointer"
@@ -15433,9 +15440,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
15433
15440
  <ng-container *ngFor="let action of resolvedProps.rightActions">
15434
15441
  <ion-button
15435
15442
  *ngIf="action.type === actionTypes.ICON"
15443
+ [attr.aria-label]="action.description"
15436
15444
  (click)="clickHandler(sections.headerRight, action.token)"
15437
15445
  >
15438
- <ion-icon slot="icon-only" [name]="action.description" color="dark"></ion-icon>
15446
+ <ion-icon slot="icon-only" [name]="action.description" color="dark" aria-hidden="true"></ion-icon>
15439
15447
  </ion-button>
15440
15448
  <val-avatar
15441
15449
  style="margin-right: 4px; cursor: pointer"
@@ -15477,7 +15485,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
15477
15485
  @if (resolvedProps.image) {
15478
15486
  <img [alt]="resolvedProps.title || 'Card image'" [src]="resolvedProps.image" />
15479
15487
  }
15480
- <ion-card-content *ngIf="resolvedProps.content" class="complex-content">{{ resolvedProps.content }}</ion-card-content>
15488
+ <ion-card-content *ngIf="resolvedProps.content" class="complex-content">{{
15489
+ resolvedProps.content
15490
+ }}</ion-card-content>
15481
15491
  </div>
15482
15492
  @if (resolvedProps.footerActions && resolvedProps.footerActions.length > 0) {
15483
15493
  <div class="card-actions">
@@ -15495,9 +15505,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
15495
15505
  <ng-container *ngFor="let action of resolvedProps.footerComplexActions">
15496
15506
  <ion-button
15497
15507
  *ngIf="action.type === actionTypes.ICON"
15508
+ [attr.aria-label]="action.description"
15498
15509
  (click)="clickHandler(sections.footerExtra, action.token)"
15499
15510
  >
15500
- <ion-icon slot="icon-only" [name]="action.description" color="dark"></ion-icon>
15511
+ <ion-icon slot="icon-only" [name]="action.description" color="dark" aria-hidden="true"></ion-icon>
15501
15512
  </ion-button>
15502
15513
  <val-avatar
15503
15514
  style="margin-right: 4px; cursor: pointer"
@@ -15719,7 +15730,12 @@ class ContentLoaderComponent {
15719
15730
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContentLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
15720
15731
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ContentLoaderComponent, isStandalone: true, selector: "val-content-loader", inputs: { props: "props" }, ngImport: i0, template: `
15721
15732
  <div [ngClass]="['spinner-wrapper', props.size]">
15722
- <ion-spinner [ngClass]="[props.size]" [name]="props.name" [color]="props.color"></ion-spinner>
15733
+ <ion-spinner
15734
+ [ngClass]="[props.size]"
15735
+ [name]="props.name"
15736
+ [color]="props.color"
15737
+ [attr.aria-label]="props.text || 'Cargando'"
15738
+ ></ion-spinner>
15723
15739
  <ion-text [color]="props.color">
15724
15740
  <p>{{ props.text }}</p>
15725
15741
  </ion-text>
@@ -15730,7 +15746,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
15730
15746
  type: Component,
15731
15747
  args: [{ selector: 'val-content-loader', standalone: true, imports: [CommonModule, IonSpinner, IonText], template: `
15732
15748
  <div [ngClass]="['spinner-wrapper', props.size]">
15733
- <ion-spinner [ngClass]="[props.size]" [name]="props.name" [color]="props.color"></ion-spinner>
15749
+ <ion-spinner
15750
+ [ngClass]="[props.size]"
15751
+ [name]="props.name"
15752
+ [color]="props.color"
15753
+ [attr.aria-label]="props.text || 'Cargando'"
15754
+ ></ion-spinner>
15734
15755
  <ion-text [color]="props.color">
15735
15756
  <p>{{ props.text }}</p>
15736
15757
  </ion-text>
@@ -16143,7 +16164,10 @@ class FileInputComponent {
16143
16164
  <div class="file-container">
16144
16165
  <input style="display: none" type="file" (change)="onFileSelected($event)" #fileInput [accept]="props.accept" />
16145
16166
  <div class="name-container">
16146
- <ion-icon [name]="selectedFile ? 'checkmark-circle-outline' : 'alert-circle-outline'"></ion-icon>
16167
+ <ion-icon
16168
+ [name]="selectedFile ? 'checkmark-circle-outline' : 'alert-circle-outline'"
16169
+ aria-hidden="true"
16170
+ ></ion-icon>
16147
16171
  <val-text
16148
16172
  style="margin-left: 4px;"
16149
16173
  [props]="{
@@ -16164,7 +16188,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
16164
16188
  <div class="file-container">
16165
16189
  <input style="display: none" type="file" (change)="onFileSelected($event)" #fileInput [accept]="props.accept" />
16166
16190
  <div class="name-container">
16167
- <ion-icon [name]="selectedFile ? 'checkmark-circle-outline' : 'alert-circle-outline'"></ion-icon>
16191
+ <ion-icon
16192
+ [name]="selectedFile ? 'checkmark-circle-outline' : 'alert-circle-outline'"
16193
+ aria-hidden="true"
16194
+ ></ion-icon>
16168
16195
  <val-text
16169
16196
  style="margin-left: 4px;"
16170
16197
  [props]="{
@@ -16410,16 +16437,16 @@ class PopoverSelectorComponent {
16410
16437
  [disabled]="props.disabled || false"
16411
16438
  class="selector-trigger"
16412
16439
  >
16413
- <ion-icon *ngIf="props.icon" [name]="props.icon" slot="start"> </ion-icon>
16440
+ <ion-icon *ngIf="props.icon" [name]="props.icon" slot="start" aria-hidden="true"> </ion-icon>
16414
16441
 
16415
16442
  <span class="trigger-text">{{ getDisplayText() }}</span>
16416
16443
 
16417
- <ion-icon name="chevron-down-outline" slot="end" class="chevron-icon"> </ion-icon>
16444
+ <ion-icon name="chevron-down-outline" slot="end" class="chevron-icon" aria-hidden="true"> </ion-icon>
16418
16445
  </ion-button>
16419
16446
 
16420
16447
  <ion-select-option *ngFor="let option of props.options" [value]="option.value" [disabled]="option.disabled">
16421
16448
  <div class="option-content">
16422
- <ion-icon *ngIf="option.icon" [name]="option.icon" class="option-icon"> </ion-icon>
16449
+ <ion-icon *ngIf="option.icon" [name]="option.icon" class="option-icon" aria-hidden="true"> </ion-icon>
16423
16450
  <span>{{ option.label }}</span>
16424
16451
  </div>
16425
16452
  </ion-select-option>
@@ -16452,16 +16479,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
16452
16479
  [disabled]="props.disabled || false"
16453
16480
  class="selector-trigger"
16454
16481
  >
16455
- <ion-icon *ngIf="props.icon" [name]="props.icon" slot="start"> </ion-icon>
16482
+ <ion-icon *ngIf="props.icon" [name]="props.icon" slot="start" aria-hidden="true"> </ion-icon>
16456
16483
 
16457
16484
  <span class="trigger-text">{{ getDisplayText() }}</span>
16458
16485
 
16459
- <ion-icon name="chevron-down-outline" slot="end" class="chevron-icon"> </ion-icon>
16486
+ <ion-icon name="chevron-down-outline" slot="end" class="chevron-icon" aria-hidden="true"> </ion-icon>
16460
16487
  </ion-button>
16461
16488
 
16462
16489
  <ion-select-option *ngFor="let option of props.options" [value]="option.value" [disabled]="option.disabled">
16463
16490
  <div class="option-content">
16464
- <ion-icon *ngIf="option.icon" [name]="option.icon" class="option-icon"> </ion-icon>
16491
+ <ion-icon *ngIf="option.icon" [name]="option.icon" class="option-icon" aria-hidden="true"> </ion-icon>
16465
16492
  <span>{{ option.label }}</span>
16466
16493
  </div>
16467
16494
  </ion-select-option>
@@ -16610,9 +16637,10 @@ class LanguageSelectorComponent {
16610
16637
  [fill]="props.fill || 'clear'"
16611
16638
  [size]="props.size || 'default'"
16612
16639
  [disabled]="props.disabled"
16640
+ [attr.aria-label]="'Cambiar idioma'"
16613
16641
  class="icon-mode-button"
16614
16642
  >
16615
- <ion-icon slot="icon-only" [name]="props.icon || 'globe-outline'"></ion-icon>
16643
+ <ion-icon slot="icon-only" [name]="props.icon || 'globe-outline'" aria-hidden="true"></ion-icon>
16616
16644
  </ion-button>
16617
16645
 
16618
16646
  <ion-popover [trigger]="popoverId" [dismissOnSelect]="true">
@@ -16627,7 +16655,7 @@ class LanguageSelectorComponent {
16627
16655
  >
16628
16656
  <ion-label>{{ getLanguageDisplayName(lang) }}</ion-label>
16629
16657
  @if (lang === currentLanguage) {
16630
- <ion-icon slot="end" name="checkmark" color="primary"></ion-icon>
16658
+ <ion-icon slot="end" name="checkmark" color="primary" aria-hidden="true"></ion-icon>
16631
16659
  }
16632
16660
  </ion-item>
16633
16661
  }
@@ -16653,9 +16681,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
16653
16681
  [fill]="props.fill || 'clear'"
16654
16682
  [size]="props.size || 'default'"
16655
16683
  [disabled]="props.disabled"
16684
+ [attr.aria-label]="'Cambiar idioma'"
16656
16685
  class="icon-mode-button"
16657
16686
  >
16658
- <ion-icon slot="icon-only" [name]="props.icon || 'globe-outline'"></ion-icon>
16687
+ <ion-icon slot="icon-only" [name]="props.icon || 'globe-outline'" aria-hidden="true"></ion-icon>
16659
16688
  </ion-button>
16660
16689
 
16661
16690
  <ion-popover [trigger]="popoverId" [dismissOnSelect]="true">
@@ -16670,7 +16699,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
16670
16699
  >
16671
16700
  <ion-label>{{ getLanguageDisplayName(lang) }}</ion-label>
16672
16701
  @if (lang === currentLanguage) {
16673
- <ion-icon slot="end" name="checkmark" color="primary"></ion-icon>
16702
+ <ion-icon slot="end" name="checkmark" color="primary" aria-hidden="true"></ion-icon>
16674
16703
  }
16675
16704
  </ion-item>
16676
16705
  }
@@ -17110,7 +17139,7 @@ class LinkComponent {
17110
17139
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: LinkComponent, isStandalone: true, selector: "val-link", inputs: { props: "props" }, outputs: { onClick: "onClick" }, ngImport: i0, template: `
17111
17140
  <div>
17112
17141
  <ion-button type="button" [color]="props.color" fill="clear" [size]="props.size" (click)="onClickHandler()">
17113
- <ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
17142
+ <ion-icon slot="end" name="chevron-forward-outline" aria-hidden="true"></ion-icon>
17114
17143
  <ion-text>{{ props.text }}</ion-text>
17115
17144
  </ion-button>
17116
17145
  </div>
@@ -17121,7 +17150,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
17121
17150
  args: [{ selector: 'val-link', standalone: true, imports: [IonButton, IonIcon, IonText], template: `
17122
17151
  <div>
17123
17152
  <ion-button type="button" [color]="props.color" fill="clear" [size]="props.size" (click)="onClickHandler()">
17124
- <ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
17153
+ <ion-icon slot="end" name="chevron-forward-outline" aria-hidden="true"></ion-icon>
17125
17154
  <ion-text>{{ props.text }}</ion-text>
17126
17155
  </ion-button>
17127
17156
  </div>
@@ -17633,7 +17662,11 @@ class PasswordInputComponent {
17633
17662
  [attr.aria-label]="toggleLabel()"
17634
17663
  [attr.aria-pressed]="!hidePassword"
17635
17664
  >
17636
- <ion-icon slot="icon-only" [name]="hidePassword ? 'eye-off-outline' : 'eye-outline'"></ion-icon>
17665
+ <ion-icon
17666
+ slot="icon-only"
17667
+ [name]="hidePassword ? 'eye-off-outline' : 'eye-outline'"
17668
+ aria-hidden="true"
17669
+ ></ion-icon>
17637
17670
  </ion-button>
17638
17671
  </div>
17639
17672
  `, isInline: true, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:var(--val-form-field-gap, .5rem) 0}@media (min-width: 768px){.input{margin:var(--val-form-field-gap, .75rem) 0}}.submit-actions--sticky{position:sticky;bottom:0;z-index:1;background:var(--ion-background-color);border-top:1px solid var(--ion-color-step-150, rgba(0, 0, 0, .08));padding:.75rem 0 calc(.75rem + env(safe-area-inset-bottom))}.field-description{display:block;font-size:.75rem;color:var(--ion-color-dark);margin-bottom:.25rem;line-height:1.4}.input-container{display:flex;align-items:center;flex-direction:row}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$7.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { 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: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
@@ -17656,7 +17689,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
17656
17689
  [attr.aria-label]="toggleLabel()"
17657
17690
  [attr.aria-pressed]="!hidePassword"
17658
17691
  >
17659
- <ion-icon slot="icon-only" [name]="hidePassword ? 'eye-off-outline' : 'eye-outline'"></ion-icon>
17692
+ <ion-icon
17693
+ slot="icon-only"
17694
+ [name]="hidePassword ? 'eye-off-outline' : 'eye-outline'"
17695
+ aria-hidden="true"
17696
+ ></ion-icon>
17660
17697
  </ion-button>
17661
17698
  </div>
17662
17699
  `, styles: ["@charset \"UTF-8\";:root{--val-container-sm: 540px;--val-container-md: 720px;--val-container-lg: 880px;--val-container-xl: 1100px;--val-container-padding: 16px;--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}body.dark,html.ion-palette-dark,body[data-theme=dark]{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:var(--val-form-field-gap, .5rem) 0}@media (min-width: 768px){.input{margin:var(--val-form-field-gap, .75rem) 0}}.submit-actions--sticky{position:sticky;bottom:0;z-index:1;background:var(--ion-background-color);border-top:1px solid var(--ion-color-step-150, rgba(0, 0, 0, .08));padding:.75rem 0 calc(.75rem + env(safe-area-inset-bottom))}.field-description{display:block;font-size:.75rem;color:var(--ion-color-dark);margin-bottom:.25rem;line-height:1.4}.input-container{display:flex;align-items:center;flex-direction:row}\n"] }]
@@ -18817,7 +18854,13 @@ class SelectSearchComponent {
18817
18854
  <ion-list>
18818
18855
  <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
18819
18856
  <ion-label>{{ item[labelProperty] }}</ion-label>
18820
- <ion-icon *ngIf="isItemSelected(item)" name="checkmark-outline" slot="end" color="primary"></ion-icon>
18857
+ <ion-icon
18858
+ *ngIf="isItemSelected(item)"
18859
+ name="checkmark-outline"
18860
+ slot="end"
18861
+ color="primary"
18862
+ aria-hidden="true"
18863
+ ></ion-icon>
18821
18864
  </ion-item>
18822
18865
  <ion-item *ngIf="filteredItems.length === 0" lines="none">
18823
18866
  <ion-label color="dark">{{ getNoResultsText() }}</ion-label>
@@ -18858,7 +18901,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
18858
18901
  <ion-list>
18859
18902
  <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
18860
18903
  <ion-label>{{ item[labelProperty] }}</ion-label>
18861
- <ion-icon *ngIf="isItemSelected(item)" name="checkmark-outline" slot="end" color="primary"></ion-icon>
18904
+ <ion-icon
18905
+ *ngIf="isItemSelected(item)"
18906
+ name="checkmark-outline"
18907
+ slot="end"
18908
+ color="primary"
18909
+ aria-hidden="true"
18910
+ ></ion-icon>
18862
18911
  </ion-item>
18863
18912
  <ion-item *ngIf="filteredItems.length === 0" lines="none">
18864
18913
  <ion-label color="dark">{{ getNoResultsText() }}</ion-label>
@@ -18964,7 +19013,7 @@ class SegmentControlComponent {
18964
19013
  @for (option of resolvedProps.options; track option.value) {
18965
19014
  <ion-segment-button [value]="option.value" [disabled]="option.disabled" [layout]="option.layout || 'icon-top'">
18966
19015
  @if (option.icon) {
18967
- <ion-icon [name]="option.icon"></ion-icon>
19016
+ <ion-icon [name]="option.icon" aria-hidden="true"></ion-icon>
18968
19017
  }
18969
19018
  @if (getOptionLabel(option)) {
18970
19019
  <ion-label>{{ getOptionLabel(option) }}</ion-label>
@@ -18989,7 +19038,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
18989
19038
  @for (option of resolvedProps.options; track option.value) {
18990
19039
  <ion-segment-button [value]="option.value" [disabled]="option.disabled" [layout]="option.layout || 'icon-top'">
18991
19040
  @if (option.icon) {
18992
- <ion-icon [name]="option.icon"></ion-icon>
19041
+ <ion-icon [name]="option.icon" aria-hidden="true"></ion-icon>
18993
19042
  }
18994
19043
  @if (getOptionLabel(option)) {
18995
19044
  <ion-label>{{ getOptionLabel(option) }}</ion-label>
@@ -19308,8 +19357,8 @@ class CodeDisplayComponent {
19308
19357
  </div>
19309
19358
  <div class="code-content">
19310
19359
  <div class="copy-button-wrapper">
19311
- <ion-button fill="clear" class="copy-button" (click)="copyToClipboard()">
19312
- <ion-icon name="copy-outline"></ion-icon>
19360
+ <ion-button fill="clear" class="copy-button" [attr.aria-label]="'Copiar'" (click)="copyToClipboard()">
19361
+ <ion-icon name="copy-outline" aria-hidden="true"></ion-icon>
19313
19362
  </ion-button>
19314
19363
  </div>
19315
19364
  <pre><code [class]="'language-' + (props.tabs[selectedTab]?.language || props.language)" #codeElement></code></pre>
@@ -19333,8 +19382,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19333
19382
  </div>
19334
19383
  <div class="code-content">
19335
19384
  <div class="copy-button-wrapper">
19336
- <ion-button fill="clear" class="copy-button" (click)="copyToClipboard()">
19337
- <ion-icon name="copy-outline"></ion-icon>
19385
+ <ion-button fill="clear" class="copy-button" [attr.aria-label]="'Copiar'" (click)="copyToClipboard()">
19386
+ <ion-icon name="copy-outline" aria-hidden="true"></ion-icon>
19338
19387
  </ion-button>
19339
19388
  </div>
19340
19389
  <pre><code [class]="'language-' + (props.tabs[selectedTab]?.language || props.language)" #codeElement></code></pre>
@@ -19456,7 +19505,7 @@ class PillComponent {
19456
19505
  <div class="notif-pill" [attr.aria-live]="'polite'">
19457
19506
  @if (resolvedProps.notification?.icon) {
19458
19507
  <div class="notif-pill__icon-wrap" [style.color]="getIconColor()">
19459
- <ion-icon [name]="resolvedProps.notification!.icon!" />
19508
+ <ion-icon [name]="resolvedProps.notification!.icon!" aria-hidden="true" />
19460
19509
  </div>
19461
19510
  }
19462
19511
 
@@ -19478,7 +19527,7 @@ class PillComponent {
19478
19527
  [attr.aria-label]="action.ariaLabel || action.token"
19479
19528
  (click)="onActionClick(action.token, $event)"
19480
19529
  >
19481
- <ion-icon [name]="action.icon" />
19530
+ <ion-icon [name]="action.icon" aria-hidden="true" />
19482
19531
  </button>
19483
19532
  }
19484
19533
  </div>
@@ -19507,7 +19556,7 @@ class PillComponent {
19507
19556
  (keydown.space)="onPillClick($event)"
19508
19557
  >
19509
19558
  @if (resolvedProps.icon) {
19510
- <ion-icon class="val-pill__icon" [name]="resolvedProps.icon" />
19559
+ <ion-icon class="val-pill__icon" [name]="resolvedProps.icon" aria-hidden="true" />
19511
19560
  }
19512
19561
  <span class="val-pill__label">{{ resolvedProps.label }}</span>
19513
19562
  </span>
@@ -19522,7 +19571,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19522
19571
  <div class="notif-pill" [attr.aria-live]="'polite'">
19523
19572
  @if (resolvedProps.notification?.icon) {
19524
19573
  <div class="notif-pill__icon-wrap" [style.color]="getIconColor()">
19525
- <ion-icon [name]="resolvedProps.notification!.icon!" />
19574
+ <ion-icon [name]="resolvedProps.notification!.icon!" aria-hidden="true" />
19526
19575
  </div>
19527
19576
  }
19528
19577
 
@@ -19544,7 +19593,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19544
19593
  [attr.aria-label]="action.ariaLabel || action.token"
19545
19594
  (click)="onActionClick(action.token, $event)"
19546
19595
  >
19547
- <ion-icon [name]="action.icon" />
19596
+ <ion-icon [name]="action.icon" aria-hidden="true" />
19548
19597
  </button>
19549
19598
  }
19550
19599
  </div>
@@ -19573,7 +19622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19573
19622
  (keydown.space)="onPillClick($event)"
19574
19623
  >
19575
19624
  @if (resolvedProps.icon) {
19576
- <ion-icon class="val-pill__icon" [name]="resolvedProps.icon" />
19625
+ <ion-icon class="val-pill__icon" [name]="resolvedProps.icon" aria-hidden="true" />
19577
19626
  }
19578
19627
  <span class="val-pill__label">{{ resolvedProps.label }}</span>
19579
19628
  </span>
@@ -19803,9 +19852,7 @@ class AccordionComponent {
19803
19852
  }
19804
19853
  }
19805
19854
  resolveProps() {
19806
- const presetProps = this.preset
19807
- ? this.presets.get('accordion', this.preset)
19808
- : {};
19855
+ const presetProps = this.preset ? this.presets.get('accordion', this.preset) : {};
19809
19856
  this.resolvedProps = {
19810
19857
  ...presetProps,
19811
19858
  ...this.props,
@@ -19833,7 +19880,7 @@ class AccordionComponent {
19833
19880
  <ion-accordion [value]="item.value" [disabled]="item.disabled">
19834
19881
  <ion-item slot="header" [color]="resolvedProps.color || 'light'">
19835
19882
  @if (item.icon) {
19836
- <ion-icon [name]="item.icon" slot="start"></ion-icon>
19883
+ <ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
19837
19884
  }
19838
19885
  <ion-label>{{ getItemHeader(item) }}</ion-label>
19839
19886
  </ion-item>
@@ -19859,7 +19906,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19859
19906
  <ion-accordion [value]="item.value" [disabled]="item.disabled">
19860
19907
  <ion-item slot="header" [color]="resolvedProps.color || 'light'">
19861
19908
  @if (item.icon) {
19862
- <ion-icon [name]="item.icon" slot="start"></ion-icon>
19909
+ <ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
19863
19910
  }
19864
19911
  <ion-label>{{ getItemHeader(item) }}</ion-label>
19865
19912
  </ion-item>
@@ -19928,9 +19975,7 @@ class TabsComponent {
19928
19975
  * Explicit props take precedence over preset values.
19929
19976
  */
19930
19977
  resolveProps() {
19931
- const presetProps = this.preset
19932
- ? this.presets.get('tabs', this.preset)
19933
- : {};
19978
+ const presetProps = this.preset ? this.presets.get('tabs', this.preset) : {};
19934
19979
  this.resolvedProps = {
19935
19980
  ...presetProps,
19936
19981
  ...this.props,
@@ -19960,7 +20005,7 @@ class TabsComponent {
19960
20005
  (click)="onTabClick(tab)"
19961
20006
  >
19962
20007
  @if (tab.icon && resolvedProps.layout !== 'icon-hide') {
19963
- <ion-icon [name]="tab.icon"></ion-icon>
20008
+ <ion-icon [name]="tab.icon" aria-hidden="true"></ion-icon>
19964
20009
  }
19965
20010
  @if (getTabLabel(tab) && resolvedProps.layout !== 'label-hide') {
19966
20011
  <ion-label>{{ getTabLabel(tab) }}</ion-label>
@@ -19990,7 +20035,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
19990
20035
  (click)="onTabClick(tab)"
19991
20036
  >
19992
20037
  @if (tab.icon && resolvedProps.layout !== 'icon-hide') {
19993
- <ion-icon [name]="tab.icon"></ion-icon>
20038
+ <ion-icon [name]="tab.icon" aria-hidden="true"></ion-icon>
19994
20039
  }
19995
20040
  @if (getTabLabel(tab) && resolvedProps.layout !== 'label-hide') {
19996
20041
  <ion-label>{{ getTabLabel(tab) }}</ion-label>
@@ -20084,11 +20129,11 @@ class BreadcrumbComponent {
20084
20129
  (click)="onBreadcrumbClick($event, item, $index)"
20085
20130
  >
20086
20131
  @if (item.icon) {
20087
- <ion-icon [name]="item.icon" slot="start"></ion-icon>
20132
+ <ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
20088
20133
  }
20089
20134
  {{ getItemLabel(item) }}
20090
20135
  @if (!isLast && resolvedProps.separatorIcon) {
20091
- <ion-icon [name]="resolvedProps.separatorIcon" slot="separator"></ion-icon>
20136
+ <ion-icon [name]="resolvedProps.separatorIcon" slot="separator" aria-hidden="true"></ion-icon>
20092
20137
  }
20093
20138
  </ion-breadcrumb>
20094
20139
  }
@@ -20113,11 +20158,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
20113
20158
  (click)="onBreadcrumbClick($event, item, $index)"
20114
20159
  >
20115
20160
  @if (item.icon) {
20116
- <ion-icon [name]="item.icon" slot="start"></ion-icon>
20161
+ <ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
20117
20162
  }
20118
20163
  {{ getItemLabel(item) }}
20119
20164
  @if (!isLast && resolvedProps.separatorIcon) {
20120
- <ion-icon [name]="resolvedProps.separatorIcon" slot="separator"></ion-icon>
20165
+ <ion-icon [name]="resolvedProps.separatorIcon" slot="separator" aria-hidden="true"></ion-icon>
20121
20166
  }
20122
20167
  </ion-breadcrumb>
20123
20168
  }
@@ -20488,9 +20533,7 @@ class StepperComponent {
20488
20533
  }
20489
20534
  }
20490
20535
  resolveProps() {
20491
- const presetProps = this.preset
20492
- ? this.presets.get('stepper', this.preset)
20493
- : {};
20536
+ const presetProps = this.preset ? this.presets.get('stepper', this.preset) : {};
20494
20537
  this.resolvedProps = {
20495
20538
  ...presetProps,
20496
20539
  ...this.props,
@@ -20501,7 +20544,7 @@ class StepperComponent {
20501
20544
  return this.resolvedProps.currentIndex;
20502
20545
  }
20503
20546
  if (this.resolvedProps.currentStep) {
20504
- return this.resolvedProps.steps?.findIndex((s) => s.value === this.resolvedProps.currentStep) ?? 0;
20547
+ return this.resolvedProps.steps?.findIndex(s => s.value === this.resolvedProps.currentStep) ?? 0;
20505
20548
  }
20506
20549
  return 0;
20507
20550
  }
@@ -20576,15 +20619,15 @@ class StepperComponent {
20576
20619
  <div class="step-indicator">
20577
20620
  <div class="step-circle" [style.--step-color]="getStepColor(step, i)">
20578
20621
  @if (getStepStatus(step, i) === 'completed') {
20579
- <ion-icon name="checkmark"></ion-icon>
20622
+ <ion-icon name="checkmark" aria-hidden="true"></ion-icon>
20580
20623
  } @else if (getStepStatus(step, i) === 'error') {
20581
- <ion-icon name="close"></ion-icon>
20624
+ <ion-icon name="close" aria-hidden="true"></ion-icon>
20582
20625
  } @else if (step.icon) {
20583
- <ion-icon [name]="step.icon"></ion-icon>
20626
+ <ion-icon [name]="step.icon" aria-hidden="true"></ion-icon>
20584
20627
  } @else if (resolvedProps.showNumbers !== false) {
20585
20628
  <span class="step-number">{{ i + 1 }}</span>
20586
20629
  } @else {
20587
- <ion-icon name="ellipse"></ion-icon>
20630
+ <ion-icon name="ellipse" aria-hidden="true"></ion-icon>
20588
20631
  }
20589
20632
  </div>
20590
20633
  @if (!isLast && resolvedProps.connectorStyle !== 'none') {
@@ -20636,15 +20679,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
20636
20679
  <div class="step-indicator">
20637
20680
  <div class="step-circle" [style.--step-color]="getStepColor(step, i)">
20638
20681
  @if (getStepStatus(step, i) === 'completed') {
20639
- <ion-icon name="checkmark"></ion-icon>
20682
+ <ion-icon name="checkmark" aria-hidden="true"></ion-icon>
20640
20683
  } @else if (getStepStatus(step, i) === 'error') {
20641
- <ion-icon name="close"></ion-icon>
20684
+ <ion-icon name="close" aria-hidden="true"></ion-icon>
20642
20685
  } @else if (step.icon) {
20643
- <ion-icon [name]="step.icon"></ion-icon>
20686
+ <ion-icon [name]="step.icon" aria-hidden="true"></ion-icon>
20644
20687
  } @else if (resolvedProps.showNumbers !== false) {
20645
20688
  <span class="step-number">{{ i + 1 }}</span>
20646
20689
  } @else {
20647
- <ion-icon name="ellipse"></ion-icon>
20690
+ <ion-icon name="ellipse" aria-hidden="true"></ion-icon>
20648
20691
  }
20649
20692
  </div>
20650
20693
  @if (!isLast && resolvedProps.connectorStyle !== 'none') {
@@ -20745,9 +20788,7 @@ class ChipGroupComponent {
20745
20788
  }
20746
20789
  }
20747
20790
  resolveProps() {
20748
- const presetProps = this.preset
20749
- ? this.presets.get('chipGroup', this.preset)
20750
- : {};
20791
+ const presetProps = this.preset ? this.presets.get('chipGroup', this.preset) : {};
20751
20792
  this.resolvedProps = {
20752
20793
  ...presetProps,
20753
20794
  ...this.props,
@@ -20773,7 +20814,7 @@ class ChipGroupComponent {
20773
20814
  }
20774
20815
  else {
20775
20816
  // Single selection: deselect all others
20776
- this.resolvedProps.chips.forEach((c) => {
20817
+ this.resolvedProps.chips.forEach(c => {
20777
20818
  c.selected = c.value === chip.value ? !c.selected : false;
20778
20819
  });
20779
20820
  }
@@ -20791,8 +20832,8 @@ class ChipGroupComponent {
20791
20832
  }
20792
20833
  }
20793
20834
  emitSelectionChange() {
20794
- const selected = this.resolvedProps.chips.filter((c) => c.selected);
20795
- const values = selected.map((c) => c.value);
20835
+ const selected = this.resolvedProps.chips.filter(c => c.selected);
20836
+ const values = selected.map(c => c.value);
20796
20837
  this.selectionChange.emit({
20797
20838
  selected: this.resolvedProps.multiple ? selected : selected[0],
20798
20839
  values: this.resolvedProps.multiple ? values : values[0],
@@ -20814,14 +20855,19 @@ class ChipGroupComponent {
20814
20855
  (keydown.space)="onChipKey($event, chip)"
20815
20856
  >
20816
20857
  @if (chip.icon) {
20817
- <ion-icon [name]="chip.icon"></ion-icon>
20858
+ <ion-icon [name]="chip.icon" aria-hidden="true"></ion-icon>
20818
20859
  }
20819
20860
  @if (chip.selected && resolvedProps.selectable) {
20820
- <ion-icon name="checkmark" class="selected-icon"></ion-icon>
20861
+ <ion-icon name="checkmark" class="selected-icon" aria-hidden="true"></ion-icon>
20821
20862
  }
20822
20863
  <ion-label>{{ getChipLabel(chip) }}</ion-label>
20823
20864
  @if (resolvedProps.removable && !chip.disabled) {
20824
- <button type="button" class="remove-button" [attr.aria-label]="removeLabel(chip)" (click)="onRemoveChip($event, chip)">
20865
+ <button
20866
+ type="button"
20867
+ class="remove-button"
20868
+ [attr.aria-label]="removeLabel(chip)"
20869
+ (click)="onRemoveChip($event, chip)"
20870
+ >
20825
20871
  <ion-icon name="close" class="remove-icon" aria-hidden="true"></ion-icon>
20826
20872
  </button>
20827
20873
  }
@@ -20847,14 +20893,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
20847
20893
  (keydown.space)="onChipKey($event, chip)"
20848
20894
  >
20849
20895
  @if (chip.icon) {
20850
- <ion-icon [name]="chip.icon"></ion-icon>
20896
+ <ion-icon [name]="chip.icon" aria-hidden="true"></ion-icon>
20851
20897
  }
20852
20898
  @if (chip.selected && resolvedProps.selectable) {
20853
- <ion-icon name="checkmark" class="selected-icon"></ion-icon>
20899
+ <ion-icon name="checkmark" class="selected-icon" aria-hidden="true"></ion-icon>
20854
20900
  }
20855
20901
  <ion-label>{{ getChipLabel(chip) }}</ion-label>
20856
20902
  @if (resolvedProps.removable && !chip.disabled) {
20857
- <button type="button" class="remove-button" [attr.aria-label]="removeLabel(chip)" (click)="onRemoveChip($event, chip)">
20903
+ <button
20904
+ type="button"
20905
+ class="remove-button"
20906
+ [attr.aria-label]="removeLabel(chip)"
20907
+ (click)="onRemoveChip($event, chip)"
20908
+ >
20858
20909
  <ion-icon name="close" class="remove-icon" aria-hidden="true"></ion-icon>
20859
20910
  </button>
20860
20911
  }
@@ -21325,7 +21376,7 @@ class StatsCardComponent {
21325
21376
  <div class="stats-header">
21326
21377
  <span class="stats-title">{{ resolvedProps.title }}</span>
21327
21378
  @if (resolvedProps.icon) {
21328
- <ion-icon [name]="resolvedProps.icon" class="stats-icon"></ion-icon>
21379
+ <ion-icon [name]="resolvedProps.icon" class="stats-icon" aria-hidden="true"></ion-icon>
21329
21380
  }
21330
21381
  </div>
21331
21382
 
@@ -21345,7 +21396,7 @@ class StatsCardComponent {
21345
21396
 
21346
21397
  @if (resolvedProps.trend && !resolvedProps.loading) {
21347
21398
  <div class="stats-trend" [class]="getTrendClass()">
21348
- <ion-icon [name]="getTrendIcon()"></ion-icon>
21399
+ <ion-icon [name]="getTrendIcon()" aria-hidden="true"></ion-icon>
21349
21400
  <span class="trend-value">{{ Math.abs(resolvedProps.trend.value) }}%</span>
21350
21401
  @if (resolvedProps.trend.label) {
21351
21402
  <span class="trend-label">{{ resolvedProps.trend.label }}</span>
@@ -21389,7 +21440,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
21389
21440
  <div class="stats-header">
21390
21441
  <span class="stats-title">{{ resolvedProps.title }}</span>
21391
21442
  @if (resolvedProps.icon) {
21392
- <ion-icon [name]="resolvedProps.icon" class="stats-icon"></ion-icon>
21443
+ <ion-icon [name]="resolvedProps.icon" class="stats-icon" aria-hidden="true"></ion-icon>
21393
21444
  }
21394
21445
  </div>
21395
21446
 
@@ -21409,7 +21460,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
21409
21460
 
21410
21461
  @if (resolvedProps.trend && !resolvedProps.loading) {
21411
21462
  <div class="stats-trend" [class]="getTrendClass()">
21412
- <ion-icon [name]="getTrendIcon()"></ion-icon>
21463
+ <ion-icon [name]="getTrendIcon()" aria-hidden="true"></ion-icon>
21413
21464
  <span class="trend-value">{{ Math.abs(resolvedProps.trend.value) }}%</span>
21414
21465
  @if (resolvedProps.trend.label) {
21415
21466
  <span class="trend-label">{{ resolvedProps.trend.label }}</span>
@@ -21539,7 +21590,7 @@ class CommentComponent {
21539
21590
  getInitials(name) {
21540
21591
  return name
21541
21592
  .split(' ')
21542
- .map((n) => n[0])
21593
+ .map(n => n[0])
21543
21594
  .join('')
21544
21595
  .substring(0, 2)
21545
21596
  .toUpperCase();
@@ -21624,8 +21675,8 @@ class CommentComponent {
21624
21675
  return item.label || item.contentFallback || '';
21625
21676
  }
21626
21677
  hasChildren() {
21627
- return !!(this.props.children && this.props.children.length > 0) ||
21628
- !!(this.props.replyCount && this.props.replyCount > 0);
21678
+ return (!!(this.props.children && this.props.children.length > 0) ||
21679
+ !!(this.props.replyCount && this.props.replyCount > 0));
21629
21680
  }
21630
21681
  canShowChildren() {
21631
21682
  const maxDepth = this.props.maxDepth ?? 3;
@@ -21698,7 +21749,7 @@ class CommentComponent {
21698
21749
  >
21699
21750
  @if (props.pinned) {
21700
21751
  <div class="pinned-indicator">
21701
- <ion-icon name="pin"></ion-icon>
21752
+ <ion-icon name="pin" aria-hidden="true"></ion-icon>
21702
21753
  <span>{{ i18n.t('pinned') }}</span>
21703
21754
  </div>
21704
21755
  }
@@ -21719,7 +21770,7 @@ class CommentComponent {
21719
21770
  <button type="button" class="author-info" [attr.aria-label]="authorLabel()" (click)="onAuthorClick()">
21720
21771
  <span class="author-name">{{ props.author.name }}</span>
21721
21772
  @if (props.author.verified) {
21722
- <ion-icon name="checkmark-circle" class="verified-badge"></ion-icon>
21773
+ <ion-icon name="checkmark-circle" class="verified-badge" aria-hidden="true"></ion-icon>
21723
21774
  }
21724
21775
  @if (props.author.username) {
21725
21776
  <span class="author-username">&#64;{{ props.author.username }}</span>
@@ -21739,14 +21790,12 @@ class CommentComponent {
21739
21790
  size="small"
21740
21791
  class="more-button"
21741
21792
  [id]="'menu-trigger-' + props.token"
21793
+ [attr.aria-label]="'Más opciones'"
21742
21794
  >
21743
- <ion-icon name="ellipsis-horizontal" slot="icon-only"></ion-icon>
21795
+ <ion-icon name="ellipsis-horizontal" slot="icon-only" aria-hidden="true"></ion-icon>
21744
21796
  </ion-button>
21745
21797
 
21746
- <ion-popover
21747
- [trigger]="'menu-trigger-' + props.token"
21748
- [dismissOnSelect]="true"
21749
- >
21798
+ <ion-popover [trigger]="'menu-trigger-' + props.token" [dismissOnSelect]="true">
21750
21799
  <ng-template>
21751
21800
  <ion-list>
21752
21801
  @for (item of props.menuItems; track item.token) {
@@ -21760,11 +21809,7 @@ class CommentComponent {
21760
21809
  (click)="onMenuItemClick(item)"
21761
21810
  >
21762
21811
  @if (item.icon) {
21763
- <ion-icon
21764
- [name]="item.icon"
21765
- slot="start"
21766
- [color]="item.color"
21767
- ></ion-icon>
21812
+ <ion-icon [name]="item.icon" slot="start" [color]="item.color" aria-hidden="true"></ion-icon>
21768
21813
  }
21769
21814
  <ion-label [color]="item.color">
21770
21815
  {{ getMenuItemLabel(item) }}
@@ -21778,10 +21823,7 @@ class CommentComponent {
21778
21823
  </div>
21779
21824
 
21780
21825
  @if (!props.collapsed) {
21781
- <div
21782
- class="comment-content"
21783
- [innerHTML]="processContent(displayContent)"
21784
- ></div>
21826
+ <div class="comment-content" [innerHTML]="processContent(displayContent)"></div>
21785
21827
 
21786
21828
  @if (props.reactions && props.reactions.length > 0) {
21787
21829
  <div class="comment-reactions">
@@ -21792,7 +21834,7 @@ class CommentComponent {
21792
21834
  [style.--reaction-color]="getReactionColor(reaction)"
21793
21835
  (click)="onReactionClick(reaction)"
21794
21836
  >
21795
- <ion-icon [name]="reaction.icon"></ion-icon>
21837
+ <ion-icon [name]="reaction.icon" aria-hidden="true"></ion-icon>
21796
21838
  @if (reaction.count > 0) {
21797
21839
  <span class="reaction-count">{{ formatCount(reaction.count) }}</span>
21798
21840
  }
@@ -21812,7 +21854,7 @@ class CommentComponent {
21812
21854
  (click)="onActionClick(action)"
21813
21855
  >
21814
21856
  @if (action.icon) {
21815
- <ion-icon [name]="action.icon" slot="start"></ion-icon>
21857
+ <ion-icon [name]="action.icon" slot="start" aria-hidden="true"></ion-icon>
21816
21858
  }
21817
21859
  {{ getActionLabel(action) }}
21818
21860
  </ion-button>
@@ -21821,7 +21863,7 @@ class CommentComponent {
21821
21863
  }
21822
21864
  } @else {
21823
21865
  <button class="expand-button" (click)="onToggleCollapse()">
21824
- <ion-icon name="chevron-down"></ion-icon>
21866
+ <ion-icon name="chevron-down" aria-hidden="true"></ion-icon>
21825
21867
  <span>{{ i18n.t('showComment') }}</span>
21826
21868
  </button>
21827
21869
  }
@@ -21832,7 +21874,7 @@ class CommentComponent {
21832
21874
  <div class="comment-children">
21833
21875
  @if (props.collapsed) {
21834
21876
  <button class="collapse-button" (click)="onToggleCollapse()">
21835
- <ion-icon name="chevron-up"></ion-icon>
21877
+ <ion-icon name="chevron-up" aria-hidden="true"></ion-icon>
21836
21878
  <span>{{ i18n.t('hideReplies') }}</span>
21837
21879
  </button>
21838
21880
  }
@@ -21852,7 +21894,7 @@ class CommentComponent {
21852
21894
 
21853
21895
  @if (hasMoreReplies()) {
21854
21896
  <button class="load-more-button" (click)="onLoadMoreClick()">
21855
- <ion-icon name="chatbubble-outline"></ion-icon>
21897
+ <ion-icon name="chatbubble-outline" aria-hidden="true"></ion-icon>
21856
21898
  <span>{{ getLoadMoreRepliesText() }}</span>
21857
21899
  </button>
21858
21900
  }
@@ -21869,16 +21911,7 @@ class CommentComponent {
21869
21911
  }
21870
21912
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommentComponent, decorators: [{
21871
21913
  type: Component,
21872
- args: [{ selector: 'val-comment', standalone: true, imports: [
21873
- CommonModule,
21874
- IonIcon,
21875
- IonButton,
21876
- IonPopover,
21877
- IonList,
21878
- IonItem,
21879
- IonLabel,
21880
- AvatarComponent,
21881
- ], template: `
21914
+ args: [{ selector: 'val-comment', standalone: true, imports: [CommonModule, IonIcon, IonButton, IonPopover, IonList, IonItem, IonLabel, AvatarComponent], template: `
21882
21915
  <div
21883
21916
  class="comment"
21884
21917
  [class.highlighted]="props.highlighted"
@@ -21888,7 +21921,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
21888
21921
  >
21889
21922
  @if (props.pinned) {
21890
21923
  <div class="pinned-indicator">
21891
- <ion-icon name="pin"></ion-icon>
21924
+ <ion-icon name="pin" aria-hidden="true"></ion-icon>
21892
21925
  <span>{{ i18n.t('pinned') }}</span>
21893
21926
  </div>
21894
21927
  }
@@ -21909,7 +21942,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
21909
21942
  <button type="button" class="author-info" [attr.aria-label]="authorLabel()" (click)="onAuthorClick()">
21910
21943
  <span class="author-name">{{ props.author.name }}</span>
21911
21944
  @if (props.author.verified) {
21912
- <ion-icon name="checkmark-circle" class="verified-badge"></ion-icon>
21945
+ <ion-icon name="checkmark-circle" class="verified-badge" aria-hidden="true"></ion-icon>
21913
21946
  }
21914
21947
  @if (props.author.username) {
21915
21948
  <span class="author-username">&#64;{{ props.author.username }}</span>
@@ -21929,14 +21962,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
21929
21962
  size="small"
21930
21963
  class="more-button"
21931
21964
  [id]="'menu-trigger-' + props.token"
21965
+ [attr.aria-label]="'Más opciones'"
21932
21966
  >
21933
- <ion-icon name="ellipsis-horizontal" slot="icon-only"></ion-icon>
21967
+ <ion-icon name="ellipsis-horizontal" slot="icon-only" aria-hidden="true"></ion-icon>
21934
21968
  </ion-button>
21935
21969
 
21936
- <ion-popover
21937
- [trigger]="'menu-trigger-' + props.token"
21938
- [dismissOnSelect]="true"
21939
- >
21970
+ <ion-popover [trigger]="'menu-trigger-' + props.token" [dismissOnSelect]="true">
21940
21971
  <ng-template>
21941
21972
  <ion-list>
21942
21973
  @for (item of props.menuItems; track item.token) {
@@ -21950,11 +21981,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
21950
21981
  (click)="onMenuItemClick(item)"
21951
21982
  >
21952
21983
  @if (item.icon) {
21953
- <ion-icon
21954
- [name]="item.icon"
21955
- slot="start"
21956
- [color]="item.color"
21957
- ></ion-icon>
21984
+ <ion-icon [name]="item.icon" slot="start" [color]="item.color" aria-hidden="true"></ion-icon>
21958
21985
  }
21959
21986
  <ion-label [color]="item.color">
21960
21987
  {{ getMenuItemLabel(item) }}
@@ -21968,10 +21995,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
21968
21995
  </div>
21969
21996
 
21970
21997
  @if (!props.collapsed) {
21971
- <div
21972
- class="comment-content"
21973
- [innerHTML]="processContent(displayContent)"
21974
- ></div>
21998
+ <div class="comment-content" [innerHTML]="processContent(displayContent)"></div>
21975
21999
 
21976
22000
  @if (props.reactions && props.reactions.length > 0) {
21977
22001
  <div class="comment-reactions">
@@ -21982,7 +22006,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
21982
22006
  [style.--reaction-color]="getReactionColor(reaction)"
21983
22007
  (click)="onReactionClick(reaction)"
21984
22008
  >
21985
- <ion-icon [name]="reaction.icon"></ion-icon>
22009
+ <ion-icon [name]="reaction.icon" aria-hidden="true"></ion-icon>
21986
22010
  @if (reaction.count > 0) {
21987
22011
  <span class="reaction-count">{{ formatCount(reaction.count) }}</span>
21988
22012
  }
@@ -22002,7 +22026,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
22002
22026
  (click)="onActionClick(action)"
22003
22027
  >
22004
22028
  @if (action.icon) {
22005
- <ion-icon [name]="action.icon" slot="start"></ion-icon>
22029
+ <ion-icon [name]="action.icon" slot="start" aria-hidden="true"></ion-icon>
22006
22030
  }
22007
22031
  {{ getActionLabel(action) }}
22008
22032
  </ion-button>
@@ -22011,7 +22035,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
22011
22035
  }
22012
22036
  } @else {
22013
22037
  <button class="expand-button" (click)="onToggleCollapse()">
22014
- <ion-icon name="chevron-down"></ion-icon>
22038
+ <ion-icon name="chevron-down" aria-hidden="true"></ion-icon>
22015
22039
  <span>{{ i18n.t('showComment') }}</span>
22016
22040
  </button>
22017
22041
  }
@@ -22022,7 +22046,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
22022
22046
  <div class="comment-children">
22023
22047
  @if (props.collapsed) {
22024
22048
  <button class="collapse-button" (click)="onToggleCollapse()">
22025
- <ion-icon name="chevron-up"></ion-icon>
22049
+ <ion-icon name="chevron-up" aria-hidden="true"></ion-icon>
22026
22050
  <span>{{ i18n.t('hideReplies') }}</span>
22027
22051
  </button>
22028
22052
  }
@@ -22042,7 +22066,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
22042
22066
 
22043
22067
  @if (hasMoreReplies()) {
22044
22068
  <button class="load-more-button" (click)="onLoadMoreClick()">
22045
- <ion-icon name="chatbubble-outline"></ion-icon>
22069
+ <ion-icon name="chatbubble-outline" aria-hidden="true"></ion-icon>
22046
22070
  <span>{{ getLoadMoreRepliesText() }}</span>
22047
22071
  </button>
22048
22072
  }
@@ -23881,7 +23905,7 @@ class DateRangeInputComponent {
23881
23905
 
23882
23906
  <!-- Separator -->
23883
23907
  <div class="date-separator">
23884
- <ion-icon name="arrow-forward-outline"></ion-icon>
23908
+ <ion-icon name="arrow-forward-outline" aria-hidden="true"></ion-icon>
23885
23909
  </div>
23886
23910
 
23887
23911
  <!-- End Date -->
@@ -23915,9 +23939,7 @@ class DateRangeInputComponent {
23915
23939
  </div>
23916
23940
 
23917
23941
  @if (showDayCount && dayCount !== null) {
23918
- <div class="day-count">
23919
- {{ dayCount }} {{ getDayLabel() }}
23920
- </div>
23942
+ <div class="day-count">{{ dayCount }} {{ getDayLabel() }}</div>
23921
23943
  }
23922
23944
 
23923
23945
  @if (props.hint && !hasError) {
@@ -23979,7 +24001,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
23979
24001
 
23980
24002
  <!-- Separator -->
23981
24003
  <div class="date-separator">
23982
- <ion-icon name="arrow-forward-outline"></ion-icon>
24004
+ <ion-icon name="arrow-forward-outline" aria-hidden="true"></ion-icon>
23983
24005
  </div>
23984
24006
 
23985
24007
  <!-- End Date -->
@@ -24013,9 +24035,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
24013
24035
  </div>
24014
24036
 
24015
24037
  @if (showDayCount && dayCount !== null) {
24016
- <div class="day-count">
24017
- {{ dayCount }} {{ getDayLabel() }}
24018
- </div>
24038
+ <div class="day-count">{{ dayCount }} {{ getDayLabel() }}</div>
24019
24039
  }
24020
24040
 
24021
24041
  @if (props.hint && !hasError) {
@@ -24702,6 +24722,7 @@ class ShareButtonsComponent {
24702
24722
  <ion-icon
24703
24723
  [slot]="props.showLabels === false || props.variant === 'icon-only' ? 'icon-only' : 'start'"
24704
24724
  [name]="getButtonIcon(button)"
24725
+ aria-hidden="true"
24705
24726
  ></ion-icon>
24706
24727
  @if (props.showLabels !== false && props.variant !== 'icon-only') {
24707
24728
  {{ getButtonLabel(button) }}
@@ -24743,6 +24764,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
24743
24764
  <ion-icon
24744
24765
  [slot]="props.showLabels === false || props.variant === 'icon-only' ? 'icon-only' : 'start'"
24745
24766
  [name]="getButtonIcon(button)"
24767
+ aria-hidden="true"
24746
24768
  ></ion-icon>
24747
24769
  @if (props.showLabels !== false && props.variant !== 'icon-only') {
24748
24770
  {{ getButtonLabel(button) }}
@@ -24793,9 +24815,7 @@ class GlowCardComponent {
24793
24815
  }
24794
24816
  }
24795
24817
  resolveProps() {
24796
- const presetProps = this.preset
24797
- ? this.presets.get('glowCard', this.preset)
24798
- : {};
24818
+ const presetProps = this.preset ? this.presets.get('glowCard', this.preset) : {};
24799
24819
  this.resolvedProps = {
24800
24820
  ...presetProps,
24801
24821
  ...this.props,
@@ -24809,7 +24829,17 @@ class GlowCardComponent {
24809
24829
  this.i18n = inject(I18nService);
24810
24830
  this.navigationService = inject(NavigationService);
24811
24831
  this.themeService = inject(ThemeService);
24812
- this.ionicColors = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
24832
+ this.ionicColors = [
24833
+ 'primary',
24834
+ 'secondary',
24835
+ 'tertiary',
24836
+ 'success',
24837
+ 'warning',
24838
+ 'danger',
24839
+ 'light',
24840
+ 'medium',
24841
+ 'dark',
24842
+ ];
24813
24843
  // RGB values with SPACE separator for CSS rgb(var() / alpha) syntax
24814
24844
  this.colorRgbMap = {
24815
24845
  primary: '112 38 223',
@@ -24975,15 +25005,12 @@ class GlowCardComponent {
24975
25005
  </p>
24976
25006
 
24977
25007
  <!-- CTA Link with expanding animation -->
24978
- <a
24979
- class="glow-card__cta"
24980
- [href]="resolvedProps.cta?.url"
24981
- (click)="onCtaClick($event)"
24982
- >
25008
+ <a class="glow-card__cta" [href]="resolvedProps.cta?.url" (click)="onCtaClick($event)">
24983
25009
  <span class="glow-card__cta-text">{{ getCtaText() }}</span>
24984
25010
  <ion-icon
24985
25011
  class="glow-card__cta-icon"
24986
25012
  [name]="resolvedProps.cta?.icon || 'arrow-forward-outline'"
25013
+ aria-hidden="true"
24987
25014
  ></ion-icon>
24988
25015
  </a>
24989
25016
  </div>
@@ -25039,15 +25066,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
25039
25066
  </p>
25040
25067
 
25041
25068
  <!-- CTA Link with expanding animation -->
25042
- <a
25043
- class="glow-card__cta"
25044
- [href]="resolvedProps.cta?.url"
25045
- (click)="onCtaClick($event)"
25046
- >
25069
+ <a class="glow-card__cta" [href]="resolvedProps.cta?.url" (click)="onCtaClick($event)">
25047
25070
  <span class="glow-card__cta-text">{{ getCtaText() }}</span>
25048
25071
  <ion-icon
25049
25072
  class="glow-card__cta-icon"
25050
25073
  [name]="resolvedProps.cta?.icon || 'arrow-forward-outline'"
25074
+ aria-hidden="true"
25051
25075
  ></ion-icon>
25052
25076
  </a>
25053
25077
  </div>
@@ -25573,7 +25597,7 @@ class FeaturesListComponent {
25573
25597
  <path [attr.d]="feature.svgPath" />
25574
25598
  </svg>
25575
25599
  } @else if (feature.icon) {
25576
- <ion-icon [name]="feature.icon" [style.font-size.px]="config().iconSize"></ion-icon>
25600
+ <ion-icon [name]="feature.icon" [style.font-size.px]="config().iconSize" aria-hidden="true"></ion-icon>
25577
25601
  }
25578
25602
  </div>
25579
25603
  <div class="feature__content">
@@ -25610,7 +25634,7 @@ class FeaturesListComponent {
25610
25634
  <path [attr.d]="feature.svgPath" />
25611
25635
  </svg>
25612
25636
  } @else if (feature.icon) {
25613
- <ion-icon [name]="feature.icon" [style.font-size.px]="config().iconSize"></ion-icon>
25637
+ <ion-icon [name]="feature.icon" [style.font-size.px]="config().iconSize" aria-hidden="true"></ion-icon>
25614
25638
  }
25615
25639
  </div>
25616
25640
  <div class="feature__content">
@@ -25682,7 +25706,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
25682
25706
  <path [attr.d]="feature.svgPath" />
25683
25707
  </svg>
25684
25708
  } @else if (feature.icon) {
25685
- <ion-icon [name]="feature.icon" [style.font-size.px]="config().iconSize"></ion-icon>
25709
+ <ion-icon [name]="feature.icon" [style.font-size.px]="config().iconSize" aria-hidden="true"></ion-icon>
25686
25710
  }
25687
25711
  </div>
25688
25712
  <div class="feature__content">
@@ -25719,7 +25743,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
25719
25743
  <path [attr.d]="feature.svgPath" />
25720
25744
  </svg>
25721
25745
  } @else if (feature.icon) {
25722
- <ion-icon [name]="feature.icon" [style.font-size.px]="config().iconSize"></ion-icon>
25746
+ <ion-icon [name]="feature.icon" [style.font-size.px]="config().iconSize" aria-hidden="true"></ion-icon>
25723
25747
  }
25724
25748
  </div>
25725
25749
  <div class="feature__content">
@@ -27591,7 +27615,7 @@ class ActionCardComponent {
27591
27615
  <!-- Icon Container -->
27592
27616
  <div class="action-card__icon" [style.color]="getIconColor()" [style.background-color]="getIconBackgroundColor()">
27593
27617
  @if (config().icon?.ionicon) {
27594
- <ion-icon [name]="config().icon!.ionicon!"></ion-icon>
27618
+ <ion-icon [name]="config().icon!.ionicon!" aria-hidden="true"></ion-icon>
27595
27619
  } @else if (config().icon?.svgPath) {
27596
27620
  <svg
27597
27621
  viewBox="0 0 24 24"
@@ -27618,7 +27642,7 @@ class ActionCardComponent {
27618
27642
 
27619
27643
  <!-- Chevron (optional) -->
27620
27644
  @if (config().showChevron && !config().disabled) {
27621
- <ion-icon name="chevron-forward-outline" class="action-card__chevron"></ion-icon>
27645
+ <ion-icon name="chevron-forward-outline" class="action-card__chevron" aria-hidden="true"></ion-icon>
27622
27646
  }
27623
27647
  </article>
27624
27648
  `, isInline: true, styles: [":host{display:flex;flex-direction:column}.action-card{position:relative;display:flex;align-items:center;flex:1;gap:1rem;padding:1rem;background:var(--card-bg, var(--ion-card-background, var(--ion-background-color)));border-radius:12px;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease,background-color .2s ease;text-decoration:none;overflow:hidden;--ripple-color: var(--ion-color-primary)}.action-card--small{padding:.75rem;gap:.75rem}.action-card--small .action-card__icon{width:36px;height:36px;font-size:1.125rem;border-radius:8px}.action-card--small .action-card__icon svg{width:18px;height:18px}.action-card--small .action-card__title{font-size:.9rem}.action-card--small .action-card__description{font-size:.8rem}.action-card--medium{padding:1rem;gap:1rem}.action-card--medium .action-card__icon{width:48px;height:48px;font-size:1.5rem;border-radius:10px}.action-card--medium .action-card__icon svg{width:24px;height:24px}.action-card--medium .action-card__title{font-size:1rem}.action-card--medium .action-card__description{font-size:.875rem}.action-card--large{padding:1.25rem;gap:1.25rem}.action-card--large .action-card__icon{width:56px;height:56px;font-size:1.75rem;border-radius:12px}.action-card--large .action-card__icon svg{width:28px;height:28px}.action-card--large .action-card__title{font-size:1.1rem}.action-card--large .action-card__description{font-size:.9rem}.action-card--bordered{border:1px solid var(--card-border-color, var(--ion-color-light-shade))}.action-card--shadowed{box-shadow:0 2px 8px #00000014}.action-card--clickable:hover{transform:translateY(-2px);box-shadow:0 4px 16px #0000001f}.action-card--clickable:focus-visible{outline:2px solid var(--ion-color-primary);outline-offset:2px}.action-card--clickable:active{transform:translateY(0)}.action-card--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.action-card__badge{position:absolute;top:8px;right:8px;padding:2px 8px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;border-radius:10px;z-index:1}.action-card__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center}.action-card__icon ion-icon{font-size:inherit}.action-card__icon svg{display:block}.action-card__icon-image{width:100%;height:100%;object-fit:cover;border-radius:8px}.action-card__content{flex:1;min-width:0}.action-card__title{margin:0 0 .25rem;font-weight:600;color:var(--ion-text-color);line-height:1.3}.action-card__description{margin:0;color:var(--ion-color-medium);line-height:1.4}.action-card__chevron{flex-shrink:0;font-size:1.25rem;color:var(--ion-color-medium);transition:transform .2s ease}.action-card--clickable:hover .action-card__chevron{transform:translate(4px)}:host-context(.dark) .action-card--shadowed,:host-context(.ion-palette-dark) .action-card--shadowed,:host-context(html.ion-palette-dark) .action-card--shadowed,:host-context(body.dark) .action-card--shadowed,:host-context([data-theme=dark]) .action-card--shadowed{box-shadow:0 2px 8px #0000004d}:host-context(.dark) .action-card--clickable:hover,:host-context(.ion-palette-dark) .action-card--clickable:hover,:host-context(html.ion-palette-dark) .action-card--clickable:hover,:host-context(body.dark) .action-card--clickable:hover,:host-context([data-theme=dark]) .action-card--clickable:hover{box-shadow:0 4px 16px #0006}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonRippleEffect, selector: "ion-ripple-effect", inputs: ["type"] }] }); }
@@ -27659,7 +27683,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
27659
27683
  <!-- Icon Container -->
27660
27684
  <div class="action-card__icon" [style.color]="getIconColor()" [style.background-color]="getIconBackgroundColor()">
27661
27685
  @if (config().icon?.ionicon) {
27662
- <ion-icon [name]="config().icon!.ionicon!"></ion-icon>
27686
+ <ion-icon [name]="config().icon!.ionicon!" aria-hidden="true"></ion-icon>
27663
27687
  } @else if (config().icon?.svgPath) {
27664
27688
  <svg
27665
27689
  viewBox="0 0 24 24"
@@ -27686,7 +27710,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
27686
27710
 
27687
27711
  <!-- Chevron (optional) -->
27688
27712
  @if (config().showChevron && !config().disabled) {
27689
- <ion-icon name="chevron-forward-outline" class="action-card__chevron"></ion-icon>
27713
+ <ion-icon name="chevron-forward-outline" class="action-card__chevron" aria-hidden="true"></ion-icon>
27690
27714
  }
27691
27715
  </article>
27692
27716
  `, styles: [":host{display:flex;flex-direction:column}.action-card{position:relative;display:flex;align-items:center;flex:1;gap:1rem;padding:1rem;background:var(--card-bg, var(--ion-card-background, var(--ion-background-color)));border-radius:12px;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease,background-color .2s ease;text-decoration:none;overflow:hidden;--ripple-color: var(--ion-color-primary)}.action-card--small{padding:.75rem;gap:.75rem}.action-card--small .action-card__icon{width:36px;height:36px;font-size:1.125rem;border-radius:8px}.action-card--small .action-card__icon svg{width:18px;height:18px}.action-card--small .action-card__title{font-size:.9rem}.action-card--small .action-card__description{font-size:.8rem}.action-card--medium{padding:1rem;gap:1rem}.action-card--medium .action-card__icon{width:48px;height:48px;font-size:1.5rem;border-radius:10px}.action-card--medium .action-card__icon svg{width:24px;height:24px}.action-card--medium .action-card__title{font-size:1rem}.action-card--medium .action-card__description{font-size:.875rem}.action-card--large{padding:1.25rem;gap:1.25rem}.action-card--large .action-card__icon{width:56px;height:56px;font-size:1.75rem;border-radius:12px}.action-card--large .action-card__icon svg{width:28px;height:28px}.action-card--large .action-card__title{font-size:1.1rem}.action-card--large .action-card__description{font-size:.9rem}.action-card--bordered{border:1px solid var(--card-border-color, var(--ion-color-light-shade))}.action-card--shadowed{box-shadow:0 2px 8px #00000014}.action-card--clickable:hover{transform:translateY(-2px);box-shadow:0 4px 16px #0000001f}.action-card--clickable:focus-visible{outline:2px solid var(--ion-color-primary);outline-offset:2px}.action-card--clickable:active{transform:translateY(0)}.action-card--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.action-card__badge{position:absolute;top:8px;right:8px;padding:2px 8px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;border-radius:10px;z-index:1}.action-card__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center}.action-card__icon ion-icon{font-size:inherit}.action-card__icon svg{display:block}.action-card__icon-image{width:100%;height:100%;object-fit:cover;border-radius:8px}.action-card__content{flex:1;min-width:0}.action-card__title{margin:0 0 .25rem;font-weight:600;color:var(--ion-text-color);line-height:1.3}.action-card__description{margin:0;color:var(--ion-color-medium);line-height:1.4}.action-card__chevron{flex-shrink:0;font-size:1.25rem;color:var(--ion-color-medium);transition:transform .2s ease}.action-card--clickable:hover .action-card__chevron{transform:translate(4px)}:host-context(.dark) .action-card--shadowed,:host-context(.ion-palette-dark) .action-card--shadowed,:host-context(html.ion-palette-dark) .action-card--shadowed,:host-context(body.dark) .action-card--shadowed,:host-context([data-theme=dark]) .action-card--shadowed{box-shadow:0 2px 8px #0000004d}:host-context(.dark) .action-card--clickable:hover,:host-context(.ion-palette-dark) .action-card--clickable:hover,:host-context(html.ion-palette-dark) .action-card--clickable:hover,:host-context(body.dark) .action-card--clickable:hover,:host-context([data-theme=dark]) .action-card--clickable:hover{box-shadow:0 4px 16px #0006}\n"] }]
@@ -27773,7 +27797,7 @@ class MediaObjectComponent {
27773
27797
  @if (config().image) {
27774
27798
  <img [src]="config().image" [alt]="config().imageAlt || config().title" />
27775
27799
  } @else if (config().icon) {
27776
- <ion-icon [name]="config().icon!"></ion-icon>
27800
+ <ion-icon [name]="config().icon!" aria-hidden="true"></ion-icon>
27777
27801
  }
27778
27802
  </div>
27779
27803
 
@@ -27814,7 +27838,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
27814
27838
  @if (config().image) {
27815
27839
  <img [src]="config().image" [alt]="config().imageAlt || config().title" />
27816
27840
  } @else if (config().icon) {
27817
- <ion-icon [name]="config().icon!"></ion-icon>
27841
+ <ion-icon [name]="config().icon!" aria-hidden="true"></ion-icon>
27818
27842
  }
27819
27843
  </div>
27820
27844
 
@@ -33765,6 +33789,7 @@ class CookieBannerComponent {
33765
33789
  role="dialog"
33766
33790
  aria-modal="false"
33767
33791
  aria-live="polite"
33792
+ [attr.aria-label]="props.ariaLabel || 'Aviso de cookies'"
33768
33793
  >
33769
33794
  <div class="val-cookie-banner__inner" [style.max-width]="props.maxWidth || '1200px'">
33770
33795
  @if (props.dismissible) {
@@ -33841,6 +33866,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
33841
33866
  role="dialog"
33842
33867
  aria-modal="false"
33843
33868
  aria-live="polite"
33869
+ [attr.aria-label]="props.ariaLabel || 'Aviso de cookies'"
33844
33870
  >
33845
33871
  <div class="val-cookie-banner__inner" [style.max-width]="props.maxWidth || '1200px'">
33846
33872
  @if (props.dismissible) {
@@ -36898,9 +36924,9 @@ class DataTableComponent {
36898
36924
  <!-- Loading overlay -->
36899
36925
  @if (props.loadingState?.loading) {
36900
36926
  <div class="loading-overlay">
36901
- <ion-spinner name="circular"></ion-spinner>
36927
+ <ion-spinner name="circular" [attr.aria-label]="props.loadingState?.message || 'Cargando'"></ion-spinner>
36902
36928
  @if (props.loadingState?.message) {
36903
- <span class="loading-message">{{ props.loadingState.message }}</span>
36929
+ <span class="loading-message" aria-hidden="true">{{ props.loadingState.message }}</span>
36904
36930
  }
36905
36931
  </div>
36906
36932
  }
@@ -36919,11 +36945,12 @@ class DataTableComponent {
36919
36945
  <tr>
36920
36946
  <!-- Selection column -->
36921
36947
  @if (props.showSelectionColumn && props.selection?.mode === 'multiple') {
36922
- <th class="selection-cell">
36948
+ <th class="selection-cell" scope="col" aria-label="Selección">
36923
36949
  <ion-checkbox
36924
36950
  [checked]="isAllSelected"
36925
36951
  [indeterminate]="isIndeterminate"
36926
36952
  (ionChange)="toggleSelectAll($event)"
36953
+ aria-label="Seleccionar todo"
36927
36954
  ></ion-checkbox>
36928
36955
  </th>
36929
36956
  }
@@ -37015,6 +37042,7 @@ class DataTableComponent {
37015
37042
  [checked]="isRowSelected(row)"
37016
37043
  (ionChange)="toggleRowSelection(row, $event)"
37017
37044
  (click)="$event.stopPropagation()"
37045
+ aria-label="Seleccionar fila"
37018
37046
  ></ion-checkbox>
37019
37047
  } @else if (props.selection?.mode === 'single') {
37020
37048
  <input
@@ -37253,9 +37281,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
37253
37281
  <!-- Loading overlay -->
37254
37282
  @if (props.loadingState?.loading) {
37255
37283
  <div class="loading-overlay">
37256
- <ion-spinner name="circular"></ion-spinner>
37284
+ <ion-spinner name="circular" [attr.aria-label]="props.loadingState?.message || 'Cargando'"></ion-spinner>
37257
37285
  @if (props.loadingState?.message) {
37258
- <span class="loading-message">{{ props.loadingState.message }}</span>
37286
+ <span class="loading-message" aria-hidden="true">{{ props.loadingState.message }}</span>
37259
37287
  }
37260
37288
  </div>
37261
37289
  }
@@ -37274,11 +37302,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
37274
37302
  <tr>
37275
37303
  <!-- Selection column -->
37276
37304
  @if (props.showSelectionColumn && props.selection?.mode === 'multiple') {
37277
- <th class="selection-cell">
37305
+ <th class="selection-cell" scope="col" aria-label="Selección">
37278
37306
  <ion-checkbox
37279
37307
  [checked]="isAllSelected"
37280
37308
  [indeterminate]="isIndeterminate"
37281
37309
  (ionChange)="toggleSelectAll($event)"
37310
+ aria-label="Seleccionar todo"
37282
37311
  ></ion-checkbox>
37283
37312
  </th>
37284
37313
  }
@@ -37370,6 +37399,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
37370
37399
  [checked]="isRowSelected(row)"
37371
37400
  (ionChange)="toggleRowSelection(row, $event)"
37372
37401
  (click)="$event.stopPropagation()"
37402
+ aria-label="Seleccionar fila"
37373
37403
  ></ion-checkbox>
37374
37404
  } @else if (props.selection?.mode === 'single') {
37375
37405
  <input
@@ -40351,7 +40381,7 @@ class LoginComponent {
40351
40381
  this.stopResetResendCooldown();
40352
40382
  }
40353
40383
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LoginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
40354
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LoginComponent, isStandalone: true, selector: "val-login", inputs: { props: "props" }, outputs: { onSuccess: "onSuccess", onError: "onError", onMFARequired: "onMFARequired" }, ngImport: i0, template: "<div class=\"val-login\" [class.val-login--card]=\"config.showCard\">\n <!-- Logo -->\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n\n <!-- Login Form -->\n <val-form [props]=\"loginFormProps()\" (onSubmit)=\"loginHandler($event)\" />\n\n <!-- OAuth Section -->\n @if (config.showOAuth && config.oauthProviders.length > 0) {\n <div class=\"oauth-separator\">\n <span>{{ t('orContinueWith') }}</span>\n </div>\n\n <div class=\"oauth-buttons\">\n @for (provider of config.oauthProviders; track provider) {\n <ion-button\n expand=\"block\"\n fill=\"outline\"\n color=\"dark\"\n (click)=\"loginWithOAuth(provider)\"\n [disabled]=\"isOAuthLoading\"\n >\n @switch (provider) { @case ('google') {\n <ion-icon slot=\"start\" name=\"logo-google\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithGoogle') }} } @case ('apple') {\n <ion-icon slot=\"start\" name=\"logo-apple\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithApple') }} } @case ('microsoft') {\n <ion-icon slot=\"start\" name=\"logo-microsoft\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithMicrosoft') }} } }\n </ion-button>\n }\n </div>\n }\n\n <!-- Register Link -->\n @if (config.showRegister) {\n <div class=\"auth-link\">\n <ion-text color=\"dark\">\n {{ t('noAccount') }}\n <a (click)=\"openRegisterModal()\">{{ t('register') }}</a>\n </ion-text>\n </div>\n }\n\n <!-- Forgot Password Link -->\n @if (config.showForgotPassword) {\n <div class=\"auth-link forgot-password\">\n <ion-text color=\"dark\">\n {{ t('forgotLink') }}\n <a (click)=\"openForgotPasswordModal()\">{{ t('recoverPassword') }}</a>\n </ion-text>\n </div>\n }\n\n <!-- Legal Notice -->\n @if (props.legal) {\n <div class=\"legal-notice\">\n <ion-text color=\"dark\">\n <p>\n {{ t('legalPrefix') }} @if (resolvedCompanyLink) {\n <a [href]=\"resolvedCompanyLink\" target=\"_blank\" rel=\"noopener noreferrer\"\n ><strong>{{ props.legal.companyName }}</strong></a\n >\n } @else {\n <strong>{{ props.legal.companyName }}</strong>\n } {{ t('legalSuffix') }} @if (props.legal.termsLink) {\n <a [href]=\"props.legal.termsLink\">{{ t('termsAndConditions') }}</a>\n } @else {\n <span>{{ t('termsAndConditions') }}</span>\n } {{ t('and') }} @if (props.legal.privacyLink) {\n <a [href]=\"props.legal.privacyLink\">{{ t('privacyPolicy') }}</a>\n } @else {\n <span>{{ t('privacyPolicy') }}</span>\n }.\n </p>\n </ion-text>\n </div>\n }\n</div>\n\n<!-- Register Modal -->\n<ion-modal [isOpen]=\"isRegisterModalOpen\" (didDismiss)=\"closeRegisterModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeRegisterModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"registerFormProps()\" (onSubmit)=\"registerHandler($event)\" />\n <div class=\"auth-link\">\n <ion-text color=\"dark\">\n {{ t('hasAccount') }}\n <a (click)=\"closeRegisterModal()\">{{ t('signIn') }}</a>\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Verify Email Modal -->\n<ion-modal [isOpen]=\"isVerifyModalOpen\" [backdropDismiss]=\"false\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeVerifyModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"verifyFormProps()\" (onSubmit)=\"verifyHandler($event)\" />\n <div class=\"resend-link\">\n <ion-text color=\"dark\">\n {{ t('noCodeReceived') }} @if (resendCooldown > 0) {\n <span class=\"cooldown\">{{ t('resendIn', { seconds: resendCooldown.toString() }) }}</span>\n } @else {\n <a (click)=\"resendCode()\">{{ t('resend') }}</a>\n }\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Forgot Password Modal -->\n<ion-modal [isOpen]=\"isForgotPasswordModalOpen\" (didDismiss)=\"closeForgotPasswordModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeForgotPasswordModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"forgotPasswordFormProps()\" (onSubmit)=\"forgotPasswordHandler($event)\" />\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Reset Password Modal -->\n<ion-modal [isOpen]=\"isResetPasswordModalOpen\" [backdropDismiss]=\"false\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeResetPasswordModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"resetPasswordFormProps()\" (onSubmit)=\"resetPasswordHandler($event)\" />\n <div class=\"resend-link\">\n <ion-text color=\"dark\">\n {{ t('noCodeReceived') }} @if (resetResendCooldown > 0) {\n <span class=\"cooldown\">{{ t('resendIn', { seconds: resetResendCooldown.toString() }) }}</span>\n } @else {\n <a (click)=\"resendResetCode()\">{{ t('resend') }}</a>\n }\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- MFA Verify Modal -->\n<ion-modal [isOpen]=\"isMFAVerifyModalOpen\" [backdropDismiss]=\"false\" (didDismiss)=\"onMFAVerifyDismissed()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeMFAVerifyModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"mfaVerifyFormProps()\" (onSubmit)=\"verifyMFAHandler($event)\" />\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".val-login{width:100%}.val-login--card{padding:1rem .75rem;background:var(--ion-color-light);border-radius:16px;box-shadow:0 2px 8px #00000014}.logo-container{max-width:130px;margin-bottom:1.5rem}.auth-link{text-align:center;margin-top:1rem;font-size:.9rem}.auth-link a{color:var(--ion-color-primary);text-decoration:none;font-weight:500;cursor:pointer}.auth-link a:hover{text-decoration:underline}.oauth-separator{display:flex;align-items:center;margin:1.5rem 0}.oauth-separator:before,.oauth-separator:after{content:\"\";flex:1;height:1px;background:var(--ion-color-medium-tint)}.oauth-separator span{padding:0 1rem;color:var(--ion-color-dark);font-size:.85rem}.oauth-buttons{margin-bottom:1rem}.oauth-buttons ion-button{--border-radius: 8px;--border-width: 1px}.oauth-buttons ion-icon{font-size:1.2rem;margin-right:.5rem}.legal-notice{margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--ion-color-medium-tint)}.legal-notice p{font-size:.75rem;line-height:1.5;text-align:center;margin:0}.legal-notice a{color:var(--ion-color-primary);text-decoration:none}.legal-notice a:hover{text-decoration:underline}.resend-link{text-align:center;margin-top:1rem;font-size:.9rem}.resend-link a{color:var(--ion-color-primary);cursor:pointer;font-weight:500}.resend-link a:hover{text-decoration:underline}.resend-link .cooldown{color:var(--ion-color-medium)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonModal, selector: "ion-modal" }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: FormComponent, selector: "val-form", inputs: ["props"], outputs: ["onSubmit", "onInvalid", "onSelectChange"] }, { kind: "component", type: ImageComponent, selector: "val-image", inputs: ["props"] }] }); }
40384
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LoginComponent, isStandalone: true, selector: "val-login", inputs: { props: "props" }, outputs: { onSuccess: "onSuccess", onError: "onError", onMFARequired: "onMFARequired" }, ngImport: i0, template: "<div class=\"val-login\" [class.val-login--card]=\"config.showCard\">\n <!-- Logo -->\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n\n <!-- Login Form -->\n <val-form [props]=\"loginFormProps()\" (onSubmit)=\"loginHandler($event)\" />\n\n <!-- OAuth Section -->\n @if (config.showOAuth && config.oauthProviders.length > 0) {\n <div class=\"oauth-separator\">\n <span>{{ t('orContinueWith') }}</span>\n </div>\n\n <div class=\"oauth-buttons\">\n @for (provider of config.oauthProviders; track provider) {\n <ion-button\n expand=\"block\"\n fill=\"outline\"\n color=\"dark\"\n (click)=\"loginWithOAuth(provider)\"\n [disabled]=\"isOAuthLoading\"\n >\n @switch (provider) { @case ('google') {\n <ion-icon slot=\"start\" name=\"logo-google\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithGoogle') }} } @case ('apple') {\n <ion-icon slot=\"start\" name=\"logo-apple\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithApple') }} } @case ('microsoft') {\n <ion-icon slot=\"start\" name=\"logo-microsoft\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithMicrosoft') }} } }\n </ion-button>\n }\n </div>\n }\n\n <!-- Register Link -->\n @if (config.showRegister) {\n <div class=\"auth-link\">\n <ion-text color=\"dark\">\n {{ t('noAccount') }}\n <a (click)=\"openRegisterModal()\">{{ t('register') }}</a>\n </ion-text>\n </div>\n }\n\n <!-- Forgot Password Link -->\n @if (config.showForgotPassword) {\n <div class=\"auth-link forgot-password\">\n <ion-text color=\"dark\">\n {{ t('forgotLink') }}\n <a (click)=\"openForgotPasswordModal()\">{{ t('recoverPassword') }}</a>\n </ion-text>\n </div>\n }\n\n <!-- Legal Notice -->\n @if (props.legal) {\n <div class=\"legal-notice\">\n <ion-text color=\"dark\">\n <p>\n {{ t('legalPrefix') }} @if (resolvedCompanyLink) {\n <a [href]=\"resolvedCompanyLink\" target=\"_blank\" rel=\"noopener noreferrer\"\n ><strong>{{ props.legal.companyName }}</strong></a\n >\n } @else {\n <strong>{{ props.legal.companyName }}</strong>\n } {{ t('legalSuffix') }} @if (props.legal.termsLink) {\n <a [href]=\"props.legal.termsLink\">{{ t('termsAndConditions') }}</a>\n } @else {\n <span>{{ t('termsAndConditions') }}</span>\n } {{ t('and') }} @if (props.legal.privacyLink) {\n <a [href]=\"props.legal.privacyLink\">{{ t('privacyPolicy') }}</a>\n } @else {\n <span>{{ t('privacyPolicy') }}</span>\n }.\n </p>\n </ion-text>\n </div>\n }\n</div>\n\n<!-- Register Modal -->\n<ion-modal [isOpen]=\"isRegisterModalOpen\" (didDismiss)=\"closeRegisterModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" [attr.aria-label]=\"t('close')\" (click)=\"closeRegisterModal()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"registerFormProps()\" (onSubmit)=\"registerHandler($event)\" />\n <div class=\"auth-link\">\n <ion-text color=\"dark\">\n {{ t('hasAccount') }}\n <a (click)=\"closeRegisterModal()\">{{ t('signIn') }}</a>\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Verify Email Modal -->\n<ion-modal [isOpen]=\"isVerifyModalOpen\" [backdropDismiss]=\"false\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" [attr.aria-label]=\"t('close')\" (click)=\"closeVerifyModal()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"verifyFormProps()\" (onSubmit)=\"verifyHandler($event)\" />\n <div class=\"resend-link\">\n <ion-text color=\"dark\">\n {{ t('noCodeReceived') }} @if (resendCooldown > 0) {\n <span class=\"cooldown\">{{ t('resendIn', { seconds: resendCooldown.toString() }) }}</span>\n } @else {\n <a (click)=\"resendCode()\">{{ t('resend') }}</a>\n }\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Forgot Password Modal -->\n<ion-modal [isOpen]=\"isForgotPasswordModalOpen\" (didDismiss)=\"closeForgotPasswordModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" [attr.aria-label]=\"t('close')\" (click)=\"closeForgotPasswordModal()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"forgotPasswordFormProps()\" (onSubmit)=\"forgotPasswordHandler($event)\" />\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Reset Password Modal -->\n<ion-modal [isOpen]=\"isResetPasswordModalOpen\" [backdropDismiss]=\"false\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" [attr.aria-label]=\"t('close')\" (click)=\"closeResetPasswordModal()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"resetPasswordFormProps()\" (onSubmit)=\"resetPasswordHandler($event)\" />\n <div class=\"resend-link\">\n <ion-text color=\"dark\">\n {{ t('noCodeReceived') }} @if (resetResendCooldown > 0) {\n <span class=\"cooldown\">{{ t('resendIn', { seconds: resetResendCooldown.toString() }) }}</span>\n } @else {\n <a (click)=\"resendResetCode()\">{{ t('resend') }}</a>\n }\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- MFA Verify Modal -->\n<ion-modal [isOpen]=\"isMFAVerifyModalOpen\" [backdropDismiss]=\"false\" (didDismiss)=\"onMFAVerifyDismissed()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeMFAVerifyModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"mfaVerifyFormProps()\" (onSubmit)=\"verifyMFAHandler($event)\" />\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".val-login{width:100%}.val-login--card{padding:1rem .75rem;background:var(--ion-color-light);border-radius:16px;box-shadow:0 2px 8px #00000014}.logo-container{max-width:130px;margin-bottom:1.5rem}.auth-link{text-align:center;margin-top:1rem;font-size:.9rem}.auth-link a{color:var(--ion-color-primary);text-decoration:none;font-weight:500;cursor:pointer}.auth-link a:hover{text-decoration:underline}.oauth-separator{display:flex;align-items:center;margin:1.5rem 0}.oauth-separator:before,.oauth-separator:after{content:\"\";flex:1;height:1px;background:var(--ion-color-medium-tint)}.oauth-separator span{padding:0 1rem;color:var(--ion-color-dark);font-size:.85rem}.oauth-buttons{margin-bottom:1rem}.oauth-buttons ion-button{--border-radius: 8px;--border-width: 1px}.oauth-buttons ion-icon{font-size:1.2rem;margin-right:.5rem}.legal-notice{margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--ion-color-medium-tint)}.legal-notice p{font-size:.75rem;line-height:1.5;text-align:center;margin:0}.legal-notice a{color:var(--ion-color-primary);text-decoration:none}.legal-notice a:hover{text-decoration:underline}.resend-link{text-align:center;margin-top:1rem;font-size:.9rem}.resend-link a{color:var(--ion-color-primary);cursor:pointer;font-weight:500}.resend-link a:hover{text-decoration:underline}.resend-link .cooldown{color:var(--ion-color-medium)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonModal, selector: "ion-modal" }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: FormComponent, selector: "val-form", inputs: ["props"], outputs: ["onSubmit", "onInvalid", "onSelectChange"] }, { kind: "component", type: ImageComponent, selector: "val-image", inputs: ["props"] }] }); }
40355
40385
  }
40356
40386
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LoginComponent, decorators: [{
40357
40387
  type: Component,
@@ -40367,7 +40397,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
40367
40397
  IonToolbar,
40368
40398
  FormComponent,
40369
40399
  ImageComponent,
40370
- ], template: "<div class=\"val-login\" [class.val-login--card]=\"config.showCard\">\n <!-- Logo -->\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n\n <!-- Login Form -->\n <val-form [props]=\"loginFormProps()\" (onSubmit)=\"loginHandler($event)\" />\n\n <!-- OAuth Section -->\n @if (config.showOAuth && config.oauthProviders.length > 0) {\n <div class=\"oauth-separator\">\n <span>{{ t('orContinueWith') }}</span>\n </div>\n\n <div class=\"oauth-buttons\">\n @for (provider of config.oauthProviders; track provider) {\n <ion-button\n expand=\"block\"\n fill=\"outline\"\n color=\"dark\"\n (click)=\"loginWithOAuth(provider)\"\n [disabled]=\"isOAuthLoading\"\n >\n @switch (provider) { @case ('google') {\n <ion-icon slot=\"start\" name=\"logo-google\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithGoogle') }} } @case ('apple') {\n <ion-icon slot=\"start\" name=\"logo-apple\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithApple') }} } @case ('microsoft') {\n <ion-icon slot=\"start\" name=\"logo-microsoft\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithMicrosoft') }} } }\n </ion-button>\n }\n </div>\n }\n\n <!-- Register Link -->\n @if (config.showRegister) {\n <div class=\"auth-link\">\n <ion-text color=\"dark\">\n {{ t('noAccount') }}\n <a (click)=\"openRegisterModal()\">{{ t('register') }}</a>\n </ion-text>\n </div>\n }\n\n <!-- Forgot Password Link -->\n @if (config.showForgotPassword) {\n <div class=\"auth-link forgot-password\">\n <ion-text color=\"dark\">\n {{ t('forgotLink') }}\n <a (click)=\"openForgotPasswordModal()\">{{ t('recoverPassword') }}</a>\n </ion-text>\n </div>\n }\n\n <!-- Legal Notice -->\n @if (props.legal) {\n <div class=\"legal-notice\">\n <ion-text color=\"dark\">\n <p>\n {{ t('legalPrefix') }} @if (resolvedCompanyLink) {\n <a [href]=\"resolvedCompanyLink\" target=\"_blank\" rel=\"noopener noreferrer\"\n ><strong>{{ props.legal.companyName }}</strong></a\n >\n } @else {\n <strong>{{ props.legal.companyName }}</strong>\n } {{ t('legalSuffix') }} @if (props.legal.termsLink) {\n <a [href]=\"props.legal.termsLink\">{{ t('termsAndConditions') }}</a>\n } @else {\n <span>{{ t('termsAndConditions') }}</span>\n } {{ t('and') }} @if (props.legal.privacyLink) {\n <a [href]=\"props.legal.privacyLink\">{{ t('privacyPolicy') }}</a>\n } @else {\n <span>{{ t('privacyPolicy') }}</span>\n }.\n </p>\n </ion-text>\n </div>\n }\n</div>\n\n<!-- Register Modal -->\n<ion-modal [isOpen]=\"isRegisterModalOpen\" (didDismiss)=\"closeRegisterModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeRegisterModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"registerFormProps()\" (onSubmit)=\"registerHandler($event)\" />\n <div class=\"auth-link\">\n <ion-text color=\"dark\">\n {{ t('hasAccount') }}\n <a (click)=\"closeRegisterModal()\">{{ t('signIn') }}</a>\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Verify Email Modal -->\n<ion-modal [isOpen]=\"isVerifyModalOpen\" [backdropDismiss]=\"false\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeVerifyModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"verifyFormProps()\" (onSubmit)=\"verifyHandler($event)\" />\n <div class=\"resend-link\">\n <ion-text color=\"dark\">\n {{ t('noCodeReceived') }} @if (resendCooldown > 0) {\n <span class=\"cooldown\">{{ t('resendIn', { seconds: resendCooldown.toString() }) }}</span>\n } @else {\n <a (click)=\"resendCode()\">{{ t('resend') }}</a>\n }\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Forgot Password Modal -->\n<ion-modal [isOpen]=\"isForgotPasswordModalOpen\" (didDismiss)=\"closeForgotPasswordModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeForgotPasswordModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"forgotPasswordFormProps()\" (onSubmit)=\"forgotPasswordHandler($event)\" />\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Reset Password Modal -->\n<ion-modal [isOpen]=\"isResetPasswordModalOpen\" [backdropDismiss]=\"false\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeResetPasswordModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"resetPasswordFormProps()\" (onSubmit)=\"resetPasswordHandler($event)\" />\n <div class=\"resend-link\">\n <ion-text color=\"dark\">\n {{ t('noCodeReceived') }} @if (resetResendCooldown > 0) {\n <span class=\"cooldown\">{{ t('resendIn', { seconds: resetResendCooldown.toString() }) }}</span>\n } @else {\n <a (click)=\"resendResetCode()\">{{ t('resend') }}</a>\n }\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- MFA Verify Modal -->\n<ion-modal [isOpen]=\"isMFAVerifyModalOpen\" [backdropDismiss]=\"false\" (didDismiss)=\"onMFAVerifyDismissed()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeMFAVerifyModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"mfaVerifyFormProps()\" (onSubmit)=\"verifyMFAHandler($event)\" />\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".val-login{width:100%}.val-login--card{padding:1rem .75rem;background:var(--ion-color-light);border-radius:16px;box-shadow:0 2px 8px #00000014}.logo-container{max-width:130px;margin-bottom:1.5rem}.auth-link{text-align:center;margin-top:1rem;font-size:.9rem}.auth-link a{color:var(--ion-color-primary);text-decoration:none;font-weight:500;cursor:pointer}.auth-link a:hover{text-decoration:underline}.oauth-separator{display:flex;align-items:center;margin:1.5rem 0}.oauth-separator:before,.oauth-separator:after{content:\"\";flex:1;height:1px;background:var(--ion-color-medium-tint)}.oauth-separator span{padding:0 1rem;color:var(--ion-color-dark);font-size:.85rem}.oauth-buttons{margin-bottom:1rem}.oauth-buttons ion-button{--border-radius: 8px;--border-width: 1px}.oauth-buttons ion-icon{font-size:1.2rem;margin-right:.5rem}.legal-notice{margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--ion-color-medium-tint)}.legal-notice p{font-size:.75rem;line-height:1.5;text-align:center;margin:0}.legal-notice a{color:var(--ion-color-primary);text-decoration:none}.legal-notice a:hover{text-decoration:underline}.resend-link{text-align:center;margin-top:1rem;font-size:.9rem}.resend-link a{color:var(--ion-color-primary);cursor:pointer;font-weight:500}.resend-link a:hover{text-decoration:underline}.resend-link .cooldown{color:var(--ion-color-medium)}\n"] }]
40400
+ ], template: "<div class=\"val-login\" [class.val-login--card]=\"config.showCard\">\n <!-- Logo -->\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n\n <!-- Login Form -->\n <val-form [props]=\"loginFormProps()\" (onSubmit)=\"loginHandler($event)\" />\n\n <!-- OAuth Section -->\n @if (config.showOAuth && config.oauthProviders.length > 0) {\n <div class=\"oauth-separator\">\n <span>{{ t('orContinueWith') }}</span>\n </div>\n\n <div class=\"oauth-buttons\">\n @for (provider of config.oauthProviders; track provider) {\n <ion-button\n expand=\"block\"\n fill=\"outline\"\n color=\"dark\"\n (click)=\"loginWithOAuth(provider)\"\n [disabled]=\"isOAuthLoading\"\n >\n @switch (provider) { @case ('google') {\n <ion-icon slot=\"start\" name=\"logo-google\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithGoogle') }} } @case ('apple') {\n <ion-icon slot=\"start\" name=\"logo-apple\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithApple') }} } @case ('microsoft') {\n <ion-icon slot=\"start\" name=\"logo-microsoft\"></ion-icon>\n {{ isOAuthLoading ? t('connecting') : t('continueWithMicrosoft') }} } }\n </ion-button>\n }\n </div>\n }\n\n <!-- Register Link -->\n @if (config.showRegister) {\n <div class=\"auth-link\">\n <ion-text color=\"dark\">\n {{ t('noAccount') }}\n <a (click)=\"openRegisterModal()\">{{ t('register') }}</a>\n </ion-text>\n </div>\n }\n\n <!-- Forgot Password Link -->\n @if (config.showForgotPassword) {\n <div class=\"auth-link forgot-password\">\n <ion-text color=\"dark\">\n {{ t('forgotLink') }}\n <a (click)=\"openForgotPasswordModal()\">{{ t('recoverPassword') }}</a>\n </ion-text>\n </div>\n }\n\n <!-- Legal Notice -->\n @if (props.legal) {\n <div class=\"legal-notice\">\n <ion-text color=\"dark\">\n <p>\n {{ t('legalPrefix') }} @if (resolvedCompanyLink) {\n <a [href]=\"resolvedCompanyLink\" target=\"_blank\" rel=\"noopener noreferrer\"\n ><strong>{{ props.legal.companyName }}</strong></a\n >\n } @else {\n <strong>{{ props.legal.companyName }}</strong>\n } {{ t('legalSuffix') }} @if (props.legal.termsLink) {\n <a [href]=\"props.legal.termsLink\">{{ t('termsAndConditions') }}</a>\n } @else {\n <span>{{ t('termsAndConditions') }}</span>\n } {{ t('and') }} @if (props.legal.privacyLink) {\n <a [href]=\"props.legal.privacyLink\">{{ t('privacyPolicy') }}</a>\n } @else {\n <span>{{ t('privacyPolicy') }}</span>\n }.\n </p>\n </ion-text>\n </div>\n }\n</div>\n\n<!-- Register Modal -->\n<ion-modal [isOpen]=\"isRegisterModalOpen\" (didDismiss)=\"closeRegisterModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" [attr.aria-label]=\"t('close')\" (click)=\"closeRegisterModal()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"registerFormProps()\" (onSubmit)=\"registerHandler($event)\" />\n <div class=\"auth-link\">\n <ion-text color=\"dark\">\n {{ t('hasAccount') }}\n <a (click)=\"closeRegisterModal()\">{{ t('signIn') }}</a>\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Verify Email Modal -->\n<ion-modal [isOpen]=\"isVerifyModalOpen\" [backdropDismiss]=\"false\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" [attr.aria-label]=\"t('close')\" (click)=\"closeVerifyModal()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"verifyFormProps()\" (onSubmit)=\"verifyHandler($event)\" />\n <div class=\"resend-link\">\n <ion-text color=\"dark\">\n {{ t('noCodeReceived') }} @if (resendCooldown > 0) {\n <span class=\"cooldown\">{{ t('resendIn', { seconds: resendCooldown.toString() }) }}</span>\n } @else {\n <a (click)=\"resendCode()\">{{ t('resend') }}</a>\n }\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Forgot Password Modal -->\n<ion-modal [isOpen]=\"isForgotPasswordModalOpen\" (didDismiss)=\"closeForgotPasswordModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" [attr.aria-label]=\"t('close')\" (click)=\"closeForgotPasswordModal()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"forgotPasswordFormProps()\" (onSubmit)=\"forgotPasswordHandler($event)\" />\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- Reset Password Modal -->\n<ion-modal [isOpen]=\"isResetPasswordModalOpen\" [backdropDismiss]=\"false\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" [attr.aria-label]=\"t('close')\" (click)=\"closeResetPasswordModal()\">\n <ion-icon name=\"close-outline\" aria-hidden=\"true\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"resetPasswordFormProps()\" (onSubmit)=\"resetPasswordHandler($event)\" />\n <div class=\"resend-link\">\n <ion-text color=\"dark\">\n {{ t('noCodeReceived') }} @if (resetResendCooldown > 0) {\n <span class=\"cooldown\">{{ t('resendIn', { seconds: resetResendCooldown.toString() }) }}</span>\n } @else {\n <a (click)=\"resendResetCode()\">{{ t('resend') }}</a>\n }\n </ion-text>\n </div>\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n\n<!-- MFA Verify Modal -->\n<ion-modal [isOpen]=\"isMFAVerifyModalOpen\" [backdropDismiss]=\"false\" (didDismiss)=\"onMFAVerifyDismissed()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-buttons slot=\"end\">\n <ion-button fill=\"clear\" (click)=\"closeMFAVerifyModal()\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content class=\"ion-padding\">\n <section class=\"modal-form-section\">\n @if (props.logo) {\n <div class=\"logo-container\">\n <val-image [props]=\"props.logo\" />\n </div>\n }\n <val-form [props]=\"mfaVerifyFormProps()\" (onSubmit)=\"verifyMFAHandler($event)\" />\n </section>\n </ion-content>\n </ng-template>\n</ion-modal>\n", styles: [".val-login{width:100%}.val-login--card{padding:1rem .75rem;background:var(--ion-color-light);border-radius:16px;box-shadow:0 2px 8px #00000014}.logo-container{max-width:130px;margin-bottom:1.5rem}.auth-link{text-align:center;margin-top:1rem;font-size:.9rem}.auth-link a{color:var(--ion-color-primary);text-decoration:none;font-weight:500;cursor:pointer}.auth-link a:hover{text-decoration:underline}.oauth-separator{display:flex;align-items:center;margin:1.5rem 0}.oauth-separator:before,.oauth-separator:after{content:\"\";flex:1;height:1px;background:var(--ion-color-medium-tint)}.oauth-separator span{padding:0 1rem;color:var(--ion-color-dark);font-size:.85rem}.oauth-buttons{margin-bottom:1rem}.oauth-buttons ion-button{--border-radius: 8px;--border-width: 1px}.oauth-buttons ion-icon{font-size:1.2rem;margin-right:.5rem}.legal-notice{margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--ion-color-medium-tint)}.legal-notice p{font-size:.75rem;line-height:1.5;text-align:center;margin:0}.legal-notice a{color:var(--ion-color-primary);text-decoration:none}.legal-notice a:hover{text-decoration:underline}.resend-link{text-align:center;margin-top:1rem;font-size:.9rem}.resend-link a{color:var(--ion-color-primary);cursor:pointer;font-weight:500}.resend-link a:hover{text-decoration:underline}.resend-link .cooldown{color:var(--ion-color-medium)}\n"] }]
40371
40401
  }], propDecorators: { props: [{
40372
40402
  type: Input
40373
40403
  }], onSuccess: [{
@@ -55400,7 +55430,7 @@ const FIELD_LIST_I18N = {
55400
55430
  };
55401
55431
 
55402
55432
  addIcons({ addOutline, trashOutline });
55403
- const I18N_NS$1 = 'FieldList';
55433
+ const I18N_NS$2 = 'FieldList';
55404
55434
  /**
55405
55435
  * `val-field-list` — editor de listas de campos repetibles (premios, rondas,
55406
55436
  * integrantes, etc.). Cada ítem es una **card** con sus campos apilados y un botón
@@ -55454,8 +55484,8 @@ class FieldListComponent {
55454
55484
  const max = this.props.max;
55455
55485
  return max == null || this.rowsSig().length < max;
55456
55486
  });
55457
- if (!this.i18n.hasNamespace(I18N_NS$1)) {
55458
- this.i18n.registerContent(I18N_NS$1, FIELD_LIST_I18N);
55487
+ if (!this.i18n.hasNamespace(I18N_NS$2)) {
55488
+ this.i18n.registerContent(I18N_NS$2, FIELD_LIST_I18N);
55459
55489
  }
55460
55490
  }
55461
55491
  ngOnChanges(changes) {
@@ -55471,7 +55501,7 @@ class FieldListComponent {
55471
55501
  }
55472
55502
  }
55473
55503
  t(key) {
55474
- return this.i18n.t(key, I18N_NS$1);
55504
+ return this.i18n.t(key, I18N_NS$2);
55475
55505
  }
55476
55506
  /** Reemplaza `{n}` por el número de fila (1-based) en el rótulo de la card. */
55477
55507
  rowLabel(template, index) {
@@ -55643,7 +55673,7 @@ const DATE_PICKER_I18N = {
55643
55673
  };
55644
55674
 
55645
55675
  addIcons({ calendarOutline, closeOutline });
55646
- const I18N_NS = 'DatePicker';
55676
+ const I18N_NS$1 = 'DatePicker';
55647
55677
  /**
55648
55678
  * `val-date-picker` — selector de fecha con calendario vanilla-calendar-pro v3
55649
55679
  * (NO ion-datetime). Se presenta como **sheet modal** (bottom sheet), igual que
@@ -55665,8 +55695,8 @@ class DatePickerComponent {
55665
55695
  this.sheetOpen = signal(false);
55666
55696
  /** true cuando el calendario ya se construyó y es visible (fade-in). */
55667
55697
  this.calReady = signal(false);
55668
- if (!this.i18n.hasNamespace(I18N_NS)) {
55669
- this.i18n.registerContent(I18N_NS, DATE_PICKER_I18N);
55698
+ if (!this.i18n.hasNamespace(I18N_NS$1)) {
55699
+ this.i18n.registerContent(I18N_NS$1, DATE_PICKER_I18N);
55670
55700
  }
55671
55701
  }
55672
55702
  get triggerId() {
@@ -55709,7 +55739,7 @@ class DatePickerComponent {
55709
55739
  this.destroyCalendar();
55710
55740
  }
55711
55741
  t(key) {
55712
- return this.i18n.t(key, I18N_NS);
55742
+ return this.i18n.t(key, I18N_NS$1);
55713
55743
  }
55714
55744
  onSheetPresent() {
55715
55745
  this.calReady.set(false);
@@ -55735,7 +55765,7 @@ class DatePickerComponent {
55735
55765
  selectedDates: value ? [value] : [],
55736
55766
  displayDateMin: (this.props.min ?? undefined),
55737
55767
  displayDateMax: (this.props.max ?? undefined),
55738
- onClickDate: (self) => {
55768
+ onClickDate: self => {
55739
55769
  const picked = self.context.selectedDates[0] ?? null;
55740
55770
  if (picked)
55741
55771
  this.apply(picked);
@@ -55800,7 +55830,7 @@ class DatePickerComponent {
55800
55830
  [class.is-placeholder]="!displayValue"
55801
55831
  (click)="sheetOpen.set(true)"
55802
55832
  >
55803
- <ion-icon name="calendar-outline" slot="start" />
55833
+ <ion-icon name="calendar-outline" slot="start" aria-hidden="true" />
55804
55834
  {{ displayValue || placeholderText }}
55805
55835
  </ion-button>
55806
55836
  </div>
@@ -55839,11 +55869,7 @@ class DatePickerComponent {
55839
55869
  }
55840
55870
 
55841
55871
  <!-- Calendario: siempre en el DOM para que #cal exista; fade-in al estar listo -->
55842
- <div
55843
- #cal
55844
- class="vdp-sheet__cal"
55845
- [class.is-ready]="calReady()"
55846
- ></div>
55872
+ <div #cal class="vdp-sheet__cal" [class.is-ready]="calReady()"></div>
55847
55873
 
55848
55874
  @if (props.clearable && displayValue) {
55849
55875
  <ion-button expand="block" fill="clear" color="medium" (click)="clear()">
@@ -55885,7 +55911,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
55885
55911
  [class.is-placeholder]="!displayValue"
55886
55912
  (click)="sheetOpen.set(true)"
55887
55913
  >
55888
- <ion-icon name="calendar-outline" slot="start" />
55914
+ <ion-icon name="calendar-outline" slot="start" aria-hidden="true" />
55889
55915
  {{ displayValue || placeholderText }}
55890
55916
  </ion-button>
55891
55917
  </div>
@@ -55924,11 +55950,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
55924
55950
  }
55925
55951
 
55926
55952
  <!-- Calendario: siempre en el DOM para que #cal exista; fade-in al estar listo -->
55927
- <div
55928
- #cal
55929
- class="vdp-sheet__cal"
55930
- [class.is-ready]="calReady()"
55931
- ></div>
55953
+ <div #cal class="vdp-sheet__cal" [class.is-ready]="calReady()"></div>
55932
55954
 
55933
55955
  @if (props.clearable && displayValue) {
55934
55956
  <ion-button expand="block" fill="clear" color="medium" (click)="clear()">
@@ -58433,6 +58455,122 @@ function beautifyLegalArticle(article) {
58433
58455
  * Soporta modo one-shot y real-time, con gate de `firebaseAuthReady`.
58434
58456
  */
58435
58457
 
58458
+ /**
58459
+ * Defaults i18n embebidos en `createPageState`. Namespace `PageState`.
58460
+ * Auto-registrados la primera vez que se llama al helper.
58461
+ */
58462
+ const PAGE_STATE_I18N = {
58463
+ es: {
58464
+ errorTitle: 'No pudimos cargar la página',
58465
+ offlineTitle: 'Sin conexión',
58466
+ offlineHint: 'Revisá tu conexión e intentá de nuevo.',
58467
+ retry: 'Reintentar',
58468
+ },
58469
+ en: {
58470
+ errorTitle: "We couldn't load the page",
58471
+ offlineTitle: "You're offline",
58472
+ offlineHint: 'Check your connection and try again.',
58473
+ retry: 'Retry',
58474
+ },
58475
+ };
58476
+
58477
+ /**
58478
+ * createPageState — helper estándar para el patrón loading/error/data de una
58479
+ * página con datos remotos (HTTP o Firestore one-shot).
58480
+ *
58481
+ * Encapsula el boilerplate repetido en cada vista:
58482
+ * - `loading` signal (true mientras carga o recarga).
58483
+ * - `loadError` signal (el error crudo o null).
58484
+ * - `errorState` computed que convierte el error a `EmptyStateMetadata` listo
58485
+ * para `<val-empty-state>`, reactivo al idioma.
58486
+ * - `reload()` function que re-ejecuta el `loader` async.
58487
+ *
58488
+ * El caller controla el template; `createPageState` solo maneja el estado:
58489
+ *
58490
+ * ```ts
58491
+ * readonly page = createPageState(
58492
+ * this.i18n,
58493
+ * async () => {
58494
+ * const res = await firstValueFrom(this.svc.getData());
58495
+ * this.items.set(res.items);
58496
+ * },
58497
+ * { errorTitle: () => this.t('errorTitle'), retryLabel: () => this.t('retry') }
58498
+ * );
58499
+ * ```
58500
+ *
58501
+ * Template:
58502
+ * ```html
58503
+ * @if (page.loading()) { <val-skeleton-layout [props]="{ preset: 'list' }" /> }
58504
+ * @else if (page.errorState(); as e) { <val-empty-state [props]="e" /> }
58505
+ * @else { <!-- content --> }
58506
+ * ```
58507
+ *
58508
+ * El helper llama a `reload()` automáticamente al construirse (carga inicial),
58509
+ * igual que el patrón clásico `void this.load()` en el constructor.
58510
+ * Para deshabilitar la carga automática, pasar `{ autoLoad: false }`.
58511
+ *
58512
+ * Para pull-to-refresh usar `connectPageRefresh(() => page.reload())` como siempre.
58513
+ */
58514
+ const I18N_NS = 'PageState';
58515
+ /**
58516
+ * Crea el estado de carga de una página.
58517
+ *
58518
+ * @param i18n - `I18nService` inyectado en la page (para reactividad al idioma).
58519
+ * @param loader - función async que carga los datos y los siembra en signals
58520
+ * propias de la page. Si lanza, el error se captura en `loadError`.
58521
+ * @param labels - labels i18n opcionales. Si se omiten usa defaults genéricos.
58522
+ * @param options - `autoLoad`: si false no carga al construirse (default true).
58523
+ */
58524
+ function createPageState(i18n, loader, labels, options) {
58525
+ if (!i18n.hasNamespace(I18N_NS)) {
58526
+ i18n.registerContent(I18N_NS, PAGE_STATE_I18N);
58527
+ }
58528
+ const loading = signal(false);
58529
+ const loadError = signal(null);
58530
+ const errorState = computed(() => {
58531
+ i18n.lang(); // reactividad al cambiar idioma
58532
+ const err = loadError();
58533
+ if (!err)
58534
+ return null;
58535
+ const interpreted = interpretError(err);
58536
+ return createErrorStateProps(err, {
58537
+ title: {
58538
+ error: labels?.errorTitle?.() ?? i18n.t('errorTitle', 'PageState'),
58539
+ offline: labels?.offlineTitle?.() ?? i18n.t('offlineTitle', 'PageState'),
58540
+ },
58541
+ description: {
58542
+ error: labels?.errorDescription?.(err) ?? interpreted.message,
58543
+ offline: labels?.offlineHint?.() ?? i18n.t('offlineHint', 'PageState'),
58544
+ },
58545
+ retryLabel: labels?.retryLabel?.() ?? i18n.t('retry', 'PageState'),
58546
+ onRetry: () => void reload(),
58547
+ retrying: loading(),
58548
+ });
58549
+ });
58550
+ async function reload() {
58551
+ loading.set(true);
58552
+ try {
58553
+ await loader();
58554
+ loadError.set(null);
58555
+ }
58556
+ catch (err) {
58557
+ loadError.set(err);
58558
+ }
58559
+ finally {
58560
+ loading.set(false);
58561
+ }
58562
+ }
58563
+ if (options?.autoLoad !== false) {
58564
+ void reload();
58565
+ }
58566
+ return {
58567
+ loading: loading.asReadonly(),
58568
+ loadError: loadError.asReadonly(),
58569
+ errorState,
58570
+ reload,
58571
+ };
58572
+ }
58573
+
58436
58574
  /**
58437
58575
  * Cross-Platform Version Helpers
58438
58576
  *
@@ -62418,14 +62556,14 @@ class FeedbackFormComponent {
62418
62556
 
62419
62557
  @if (error()) {
62420
62558
  <div class="feedback-alert error">
62421
- <ion-icon name="close-circle-outline"></ion-icon>
62559
+ <ion-icon name="close-circle-outline" aria-hidden="true"></ion-icon>
62422
62560
  <span>{{ error() }}</span>
62423
62561
  </div>
62424
62562
  }
62425
62563
 
62426
62564
  @if (isSuccess()) {
62427
62565
  <div class="feedback-alert success">
62428
- <ion-icon name="checkmark-circle-outline"></ion-icon>
62566
+ <ion-icon name="checkmark-circle-outline" aria-hidden="true"></ion-icon>
62429
62567
  <span>{{ props.successMessage || i18n.t('feedbackSuccess') }}</span>
62430
62568
  </div>
62431
62569
  }
@@ -62453,14 +62591,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
62453
62591
 
62454
62592
  @if (error()) {
62455
62593
  <div class="feedback-alert error">
62456
- <ion-icon name="close-circle-outline"></ion-icon>
62594
+ <ion-icon name="close-circle-outline" aria-hidden="true"></ion-icon>
62457
62595
  <span>{{ error() }}</span>
62458
62596
  </div>
62459
62597
  }
62460
62598
 
62461
62599
  @if (isSuccess()) {
62462
62600
  <div class="feedback-alert success">
62463
- <ion-icon name="checkmark-circle-outline"></ion-icon>
62601
+ <ion-icon name="checkmark-circle-outline" aria-hidden="true"></ion-icon>
62464
62602
  <span>{{ props.successMessage || i18n.t('feedbackSuccess') }}</span>
62465
62603
  </div>
62466
62604
  }
@@ -63494,7 +63632,7 @@ class DocsNavLinksComponent {
63494
63632
  [href]="getHref(props.previous.route)"
63495
63633
  (click)="onNavigate($event, props.previous.route)"
63496
63634
  >
63497
- <ion-icon name="arrow-back-outline" class="docs-nav-links__icon"></ion-icon>
63635
+ <ion-icon name="arrow-back-outline" class="docs-nav-links__icon" aria-hidden="true"></ion-icon>
63498
63636
  <div class="docs-nav-links__text">
63499
63637
  <span class="docs-nav-links__label">{{ props.previous.label || previousLabel() }}</span>
63500
63638
  <span class="docs-nav-links__title">{{ props.previous.title }}</span>
@@ -63504,10 +63642,7 @@ class DocsNavLinksComponent {
63504
63642
  </div>
63505
63643
 
63506
63644
  <!-- Next -->
63507
- <div
63508
- class="docs-nav-links__item docs-nav-links__item--next"
63509
- [class.docs-nav-links__item--empty]="!props.next"
63510
- >
63645
+ <div class="docs-nav-links__item docs-nav-links__item--next" [class.docs-nav-links__item--empty]="!props.next">
63511
63646
  @if (props.next) {
63512
63647
  <a
63513
63648
  class="docs-nav-links__link"
@@ -63518,7 +63653,7 @@ class DocsNavLinksComponent {
63518
63653
  <span class="docs-nav-links__label">{{ props.next.label || nextLabel() }}</span>
63519
63654
  <span class="docs-nav-links__title">{{ props.next.title }}</span>
63520
63655
  </div>
63521
- <ion-icon name="arrow-forward-outline" class="docs-nav-links__icon"></ion-icon>
63656
+ <ion-icon name="arrow-forward-outline" class="docs-nav-links__icon" aria-hidden="true"></ion-icon>
63522
63657
  </a>
63523
63658
  }
63524
63659
  </div>
@@ -63540,7 +63675,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
63540
63675
  [href]="getHref(props.previous.route)"
63541
63676
  (click)="onNavigate($event, props.previous.route)"
63542
63677
  >
63543
- <ion-icon name="arrow-back-outline" class="docs-nav-links__icon"></ion-icon>
63678
+ <ion-icon name="arrow-back-outline" class="docs-nav-links__icon" aria-hidden="true"></ion-icon>
63544
63679
  <div class="docs-nav-links__text">
63545
63680
  <span class="docs-nav-links__label">{{ props.previous.label || previousLabel() }}</span>
63546
63681
  <span class="docs-nav-links__title">{{ props.previous.title }}</span>
@@ -63550,10 +63685,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
63550
63685
  </div>
63551
63686
 
63552
63687
  <!-- Next -->
63553
- <div
63554
- class="docs-nav-links__item docs-nav-links__item--next"
63555
- [class.docs-nav-links__item--empty]="!props.next"
63556
- >
63688
+ <div class="docs-nav-links__item docs-nav-links__item--next" [class.docs-nav-links__item--empty]="!props.next">
63557
63689
  @if (props.next) {
63558
63690
  <a
63559
63691
  class="docs-nav-links__link"
@@ -63564,7 +63696,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
63564
63696
  <span class="docs-nav-links__label">{{ props.next.label || nextLabel() }}</span>
63565
63697
  <span class="docs-nav-links__title">{{ props.next.title }}</span>
63566
63698
  </div>
63567
- <ion-icon name="arrow-forward-outline" class="docs-nav-links__icon"></ion-icon>
63699
+ <ion-icon name="arrow-forward-outline" class="docs-nav-links__icon" aria-hidden="true"></ion-icon>
63568
63700
  </a>
63569
63701
  }
63570
63702
  </div>
@@ -63893,7 +64025,7 @@ class DocsCodeExampleComponent {
63893
64025
  rel="noopener noreferrer"
63894
64026
  >
63895
64027
  {{ props.externalLink.label || 'Open in StackBlitz' }}
63896
- <ion-icon name="open-outline"></ion-icon>
64028
+ <ion-icon name="open-outline" aria-hidden="true"></ion-icon>
63897
64029
  </a>
63898
64030
  }
63899
64031
  </div>
@@ -63934,7 +64066,11 @@ class DocsCodeExampleComponent {
63934
64066
  [attr.aria-label]="copied() ? 'Code copied' : 'Copy code'"
63935
64067
  (click)="copyCode()"
63936
64068
  >
63937
- <ion-icon slot="icon-only" [name]="copied() ? 'checkmark-outline' : 'copy-outline'"></ion-icon>
64069
+ <ion-icon
64070
+ slot="icon-only"
64071
+ [name]="copied() ? 'checkmark-outline' : 'copy-outline'"
64072
+ aria-hidden="true"
64073
+ ></ion-icon>
63938
64074
  </ion-button>
63939
64075
  }
63940
64076
  </div>
@@ -63973,7 +64109,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
63973
64109
  rel="noopener noreferrer"
63974
64110
  >
63975
64111
  {{ props.externalLink.label || 'Open in StackBlitz' }}
63976
- <ion-icon name="open-outline"></ion-icon>
64112
+ <ion-icon name="open-outline" aria-hidden="true"></ion-icon>
63977
64113
  </a>
63978
64114
  }
63979
64115
  </div>
@@ -64014,7 +64150,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
64014
64150
  [attr.aria-label]="copied() ? 'Code copied' : 'Copy code'"
64015
64151
  (click)="copyCode()"
64016
64152
  >
64017
- <ion-icon slot="icon-only" [name]="copied() ? 'checkmark-outline' : 'copy-outline'"></ion-icon>
64153
+ <ion-icon
64154
+ slot="icon-only"
64155
+ [name]="copied() ? 'checkmark-outline' : 'copy-outline'"
64156
+ aria-hidden="true"
64157
+ ></ion-icon>
64018
64158
  </ion-button>
64019
64159
  }
64020
64160
  </div>
@@ -64094,9 +64234,7 @@ class DocsSearchComponent {
64094
64234
  });
64095
64235
  return results.slice(0, 10); // Limit results
64096
64236
  });
64097
- this.searchSubject
64098
- .pipe(debounceTime$1(this.props.debounceMs || 150), takeUntil$1(this.destroy$))
64099
- .subscribe((query) => {
64237
+ this.searchSubject.pipe(debounceTime$1(this.props.debounceMs || 150), takeUntil$1(this.destroy$)).subscribe(query => {
64100
64238
  this.search.emit(query);
64101
64239
  });
64102
64240
  }
@@ -64128,11 +64266,11 @@ class DocsSearchComponent {
64128
64266
  switch (event.key) {
64129
64267
  case 'ArrowDown':
64130
64268
  event.preventDefault();
64131
- this.selectedIndex.update((i) => Math.min(i + 1, resultsArray.length - 1));
64269
+ this.selectedIndex.update(i => Math.min(i + 1, resultsArray.length - 1));
64132
64270
  break;
64133
64271
  case 'ArrowUp':
64134
64272
  event.preventDefault();
64135
- this.selectedIndex.update((i) => Math.max(i - 1, 0));
64273
+ this.selectedIndex.update(i => Math.max(i - 1, 0));
64136
64274
  break;
64137
64275
  case 'Enter':
64138
64276
  event.preventDefault();
@@ -64161,7 +64299,7 @@ class DocsSearchComponent {
64161
64299
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DocsSearchComponent, isStandalone: true, selector: "val-docs-search", inputs: { props: "props" }, outputs: { navigate: "navigate", search: "search" }, host: { listeners: { "document:keydown": "onGlobalKeydown($event)" } }, viewQueries: [{ propertyName: "searchInputEl", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: `
64162
64300
  <div class="docs-search" [class]="props.cssClass">
64163
64301
  <div class="docs-search__input-wrapper">
64164
- <ion-icon name="search-outline" class="docs-search__icon"></ion-icon>
64302
+ <ion-icon name="search-outline" class="docs-search__icon" aria-hidden="true"></ion-icon>
64165
64303
  <input
64166
64304
  #searchInput
64167
64305
  type="text"
@@ -64176,13 +64314,8 @@ class DocsSearchComponent {
64176
64314
  autocomplete="off"
64177
64315
  />
64178
64316
  @if (searchQuery()) {
64179
- <button
64180
- type="button"
64181
- class="docs-search__clear"
64182
- (click)="clearSearch()"
64183
- aria-label="Clear search"
64184
- >
64185
- <ion-icon name="close-outline"></ion-icon>
64317
+ <button type="button" class="docs-search__clear" (click)="clearSearch()" aria-label="Clear search">
64318
+ <ion-icon name="close-outline" aria-hidden="true"></ion-icon>
64186
64319
  </button>
64187
64320
  } @else if (props.showShortcut) {
64188
64321
  <span class="docs-search__shortcut">{{ isMac ? '⌘' : 'Ctrl' }}+K</span>
@@ -64212,9 +64345,7 @@ class DocsSearchComponent {
64212
64345
  }
64213
64346
 
64214
64347
  @if (showResults() && searchQuery() && results().length === 0) {
64215
- <div class="docs-search__no-results">
64216
- No results found for "{{ searchQuery() }}"
64217
- </div>
64348
+ <div class="docs-search__no-results">No results found for "{{ searchQuery() }}"</div>
64218
64349
  }
64219
64350
  </div>
64220
64351
  `, isInline: true, styles: [".docs-search{--search-bg: var(--ion-background-color, #fff);--search-border: var(--ion-border-color, #e0e0e0);--search-text: var(--ion-text-color, #1a1a1a);--search-placeholder: var(--ion-color-medium, #666);--search-hover-bg: rgba(0, 0, 0, .03);--search-active-bg: rgba(0, 0, 0, .05);position:relative;font-family:var(--ion-font-family, system-ui, sans-serif)}.docs-search__input-wrapper{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;background:var(--search-bg);border:1px solid var(--search-border);border-radius:8px;transition:all .15s ease}.docs-search__input-wrapper:focus-within{border-color:#1a1a1a;box-shadow:0 0 0 3px #0000000d}.docs-search__icon{font-size:1rem;color:var(--search-placeholder);flex-shrink:0}.docs-search__input{flex:1;border:none;outline:none;background:transparent;font-size:.875rem;color:var(--search-text);min-width:0}.docs-search__input::placeholder{color:var(--search-placeholder)}.docs-search__clear{display:flex;align-items:center;justify-content:center;padding:.25rem;border:none;background:transparent;color:var(--search-placeholder);cursor:pointer;border-radius:4px;transition:all .15s ease}.docs-search__clear:hover{background:var(--search-hover-bg);color:var(--search-text)}.docs-search__clear:focus-visible{outline:2px solid #1a1a1a;outline-offset:2px}.docs-search__clear ion-icon{font-size:.875rem}.docs-search__shortcut{font-size:.6875rem;font-weight:500;color:var(--search-placeholder);background:var(--search-hover-bg);padding:.125rem .375rem;border-radius:4px;white-space:nowrap}.docs-search__results{position:absolute;top:calc(100% + 4px);left:0;right:0;max-height:400px;overflow-y:auto;background:var(--search-bg);border:1px solid var(--search-border);border-radius:8px;box-shadow:0 4px 16px #0000001a;z-index:100}.docs-search__result{display:flex;flex-direction:column;gap:.125rem;width:100%;padding:.75rem 1rem;border:none;background:transparent;text-align:left;cursor:pointer;transition:background .15s ease;border-bottom:1px solid var(--search-border)}.docs-search__result:last-child{border-bottom:none}.docs-search__result:hover,.docs-search__result--active{background:var(--search-hover-bg)}.docs-search__result:focus-visible{outline:2px solid #1a1a1a;outline-offset:-2px}.docs-search__result-section{font-size:.625rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--search-placeholder)}.docs-search__result-label{font-size:.875rem;font-weight:500;color:var(--search-text)}.docs-search__result-description{font-size:.75rem;color:var(--search-placeholder);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.docs-search__no-results{padding:1.5rem 1rem;text-align:center;font-size:.875rem;color:var(--search-placeholder);background:var(--search-bg);border:1px solid var(--search-border);border-radius:8px;box-shadow:0 4px 16px #0000001a;position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:100}:host-context(.dark) .docs-search,:host-context([color-scheme=dark]) .docs-search{--search-bg: #1e1e1e;--search-border: #3a3a3a;--search-text: #f4f5f8;--search-placeholder: #a0a0a0;--search-hover-bg: rgba(255, 255, 255, .05);--search-active-bg: rgba(255, 255, 255, .08)}:host-context(.dark) .docs-search__input-wrapper:focus-within,:host-context([color-scheme=dark]) .docs-search__input-wrapper:focus-within{border-color:#f4f5f8;box-shadow:0 0 0 3px #ffffff0d}:host-context(.dark) .docs-search__results,:host-context(.dark) .docs-search__no-results,:host-context([color-scheme=dark]) .docs-search__results,:host-context([color-scheme=dark]) .docs-search__no-results{box-shadow:0 4px 16px #0000004d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
@@ -64224,7 +64355,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
64224
64355
  args: [{ selector: 'val-docs-search', standalone: true, imports: [CommonModule, FormsModule, IonIcon], template: `
64225
64356
  <div class="docs-search" [class]="props.cssClass">
64226
64357
  <div class="docs-search__input-wrapper">
64227
- <ion-icon name="search-outline" class="docs-search__icon"></ion-icon>
64358
+ <ion-icon name="search-outline" class="docs-search__icon" aria-hidden="true"></ion-icon>
64228
64359
  <input
64229
64360
  #searchInput
64230
64361
  type="text"
@@ -64239,13 +64370,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
64239
64370
  autocomplete="off"
64240
64371
  />
64241
64372
  @if (searchQuery()) {
64242
- <button
64243
- type="button"
64244
- class="docs-search__clear"
64245
- (click)="clearSearch()"
64246
- aria-label="Clear search"
64247
- >
64248
- <ion-icon name="close-outline"></ion-icon>
64373
+ <button type="button" class="docs-search__clear" (click)="clearSearch()" aria-label="Clear search">
64374
+ <ion-icon name="close-outline" aria-hidden="true"></ion-icon>
64249
64375
  </button>
64250
64376
  } @else if (props.showShortcut) {
64251
64377
  <span class="docs-search__shortcut">{{ isMac ? '⌘' : 'Ctrl' }}+K</span>
@@ -64275,9 +64401,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
64275
64401
  }
64276
64402
 
64277
64403
  @if (showResults() && searchQuery() && results().length === 0) {
64278
- <div class="docs-search__no-results">
64279
- No results found for "{{ searchQuery() }}"
64280
- </div>
64404
+ <div class="docs-search__no-results">No results found for "{{ searchQuery() }}"</div>
64281
64405
  }
64282
64406
  </div>
64283
64407
  `, styles: [".docs-search{--search-bg: var(--ion-background-color, #fff);--search-border: var(--ion-border-color, #e0e0e0);--search-text: var(--ion-text-color, #1a1a1a);--search-placeholder: var(--ion-color-medium, #666);--search-hover-bg: rgba(0, 0, 0, .03);--search-active-bg: rgba(0, 0, 0, .05);position:relative;font-family:var(--ion-font-family, system-ui, sans-serif)}.docs-search__input-wrapper{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;background:var(--search-bg);border:1px solid var(--search-border);border-radius:8px;transition:all .15s ease}.docs-search__input-wrapper:focus-within{border-color:#1a1a1a;box-shadow:0 0 0 3px #0000000d}.docs-search__icon{font-size:1rem;color:var(--search-placeholder);flex-shrink:0}.docs-search__input{flex:1;border:none;outline:none;background:transparent;font-size:.875rem;color:var(--search-text);min-width:0}.docs-search__input::placeholder{color:var(--search-placeholder)}.docs-search__clear{display:flex;align-items:center;justify-content:center;padding:.25rem;border:none;background:transparent;color:var(--search-placeholder);cursor:pointer;border-radius:4px;transition:all .15s ease}.docs-search__clear:hover{background:var(--search-hover-bg);color:var(--search-text)}.docs-search__clear:focus-visible{outline:2px solid #1a1a1a;outline-offset:2px}.docs-search__clear ion-icon{font-size:.875rem}.docs-search__shortcut{font-size:.6875rem;font-weight:500;color:var(--search-placeholder);background:var(--search-hover-bg);padding:.125rem .375rem;border-radius:4px;white-space:nowrap}.docs-search__results{position:absolute;top:calc(100% + 4px);left:0;right:0;max-height:400px;overflow-y:auto;background:var(--search-bg);border:1px solid var(--search-border);border-radius:8px;box-shadow:0 4px 16px #0000001a;z-index:100}.docs-search__result{display:flex;flex-direction:column;gap:.125rem;width:100%;padding:.75rem 1rem;border:none;background:transparent;text-align:left;cursor:pointer;transition:background .15s ease;border-bottom:1px solid var(--search-border)}.docs-search__result:last-child{border-bottom:none}.docs-search__result:hover,.docs-search__result--active{background:var(--search-hover-bg)}.docs-search__result:focus-visible{outline:2px solid #1a1a1a;outline-offset:-2px}.docs-search__result-section{font-size:.625rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--search-placeholder)}.docs-search__result-label{font-size:.875rem;font-weight:500;color:var(--search-text)}.docs-search__result-description{font-size:.75rem;color:var(--search-placeholder);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.docs-search__no-results{padding:1.5rem 1rem;text-align:center;font-size:.875rem;color:var(--search-placeholder);background:var(--search-bg);border:1px solid var(--search-border);border-radius:8px;box-shadow:0 4px 16px #0000001a;position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:100}:host-context(.dark) .docs-search,:host-context([color-scheme=dark]) .docs-search{--search-bg: #1e1e1e;--search-border: #3a3a3a;--search-text: #f4f5f8;--search-placeholder: #a0a0a0;--search-hover-bg: rgba(255, 255, 255, .05);--search-active-bg: rgba(255, 255, 255, .08)}:host-context(.dark) .docs-search__input-wrapper:focus-within,:host-context([color-scheme=dark]) .docs-search__input-wrapper:focus-within{border-color:#f4f5f8;box-shadow:0 0 0 3px #ffffff0d}:host-context(.dark) .docs-search__results,:host-context(.dark) .docs-search__no-results,:host-context([color-scheme=dark]) .docs-search__results,:host-context([color-scheme=dark]) .docs-search__no-results{box-shadow:0 4px 16px #0000004d}\n"] }]
@@ -65848,9 +65972,10 @@ class MetricCardComponent {
65848
65972
  fill="clear"
65849
65973
  size="small"
65850
65974
  [disabled]="action.disabled ?? false"
65975
+ [attr.aria-label]="action.token"
65851
65976
  (click)="onAction.emit(action.token)"
65852
65977
  >
65853
- <ion-icon [name]="action.icon" slot="icon-only"></ion-icon>
65978
+ <ion-icon [name]="action.icon" slot="icon-only" aria-hidden="true"></ion-icon>
65854
65979
  </ion-button>
65855
65980
  }
65856
65981
  </div>
@@ -65900,9 +66025,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
65900
66025
  fill="clear"
65901
66026
  size="small"
65902
66027
  [disabled]="action.disabled ?? false"
66028
+ [attr.aria-label]="action.token"
65903
66029
  (click)="onAction.emit(action.token)"
65904
66030
  >
65905
- <ion-icon [name]="action.icon" slot="icon-only"></ion-icon>
66031
+ <ion-icon [name]="action.icon" slot="icon-only" aria-hidden="true"></ion-icon>
65906
66032
  </ion-button>
65907
66033
  }
65908
66034
  </div>
@@ -66248,7 +66374,7 @@ class TicketCardComponent {
66248
66374
  <div class="ticket-card__qr-fallback">{{ tokenShort() }}</div>
66249
66375
  } @else {
66250
66376
  <div class="ticket-card__qr-loading">
66251
- <ion-spinner name="crescent" />
66377
+ <ion-spinner name="crescent" aria-label="Generando QR" />
66252
66378
  </div>
66253
66379
  }
66254
66380
  </div>
@@ -66282,7 +66408,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
66282
66408
  <div class="ticket-card__qr-fallback">{{ tokenShort() }}</div>
66283
66409
  } @else {
66284
66410
  <div class="ticket-card__qr-loading">
66285
- <ion-spinner name="crescent" />
66411
+ <ion-spinner name="crescent" aria-label="Generando QR" />
66286
66412
  </div>
66287
66413
  }
66288
66414
  </div>
@@ -66640,5 +66766,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
66640
66766
  * Generated bundle index. Do not edit.
66641
66767
  */
66642
66768
 
66643
- export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AboutViewComponent, AccordionComponent, AccountViewComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimatedTerminalComponent, ApiKeyCreateModalComponent, ApiKeyService, ApiKeysModalComponent, ApiKeysViewComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentService, ContentTransformer, CookieBannerComponent, CountdownComponent, CreateOrgModalComponent, CtaCardComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_APP_VERSION_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_BUTTON_PRESETS, DEFAULT_CANCEL_BUTTON, DEFAULT_CHECK_INTERVAL_MS, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DEBUG_CONSOLE_CONFIG, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_PRESETS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DataTableComponent, DateInputComponent, DatePickerComponent, DateRangeInputComponent, DebugConsoleComponent, DeleteAccountModalComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EditOrgModalComponent, EmptyStateComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FieldListComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FontSizeOption, FontSizeService, FooterComponent, FooterLinksComponent, FormComponent, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HasPermissionDirective, HeaderComponent, HintComponent, HorizontalScrollComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, INVITATION_CARD_DEFAULTS, IONIC_COLORS$5 as IONIC_COLORS, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, InvitationCardComponent, InviteMemberModalComponent, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginAttemptModalComponent, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, METRIC_CARD_DEFAULTS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MemberCardComponent, MemberDetailModalComponent, MemberImportModalComponent, MenuComponent, MessagingService, MetaService, MetricCardComponent, MfaModalComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationPreferencesViewComponent, NotificationsService, NotificationsViewComponent, NumberFromToComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OrgInfoSheetComponent, OrgService, OrgSwitchService, OrganizationViewComponent, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PLATFORM_CONFIGS, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PermissionCatalogService, PermissionSelectorComponent, PermissionsViewComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PreferencesViewComponent, PresetService, PriceTagComponent, ProcessLinksPipe, ProfileSkeletonComponent, ProfileViewComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QrScannerComponent, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestService, RightsFooterComponent, RotatingTextComponent, SEARCH_HEADER_DEFAULTS, SETTINGS_SECTIONS_CATALOG, SHAPE_KEYS, SHARE_PROFILE_MODAL_DEFAULTS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, STATS_BAR_DEFAULTS, STROKE_KEYS, SearchHeaderComponent, SearchSelectorComponent, SearchbarComponent, SecurityViewComponent, SegmentControlComponent, SelectSearchComponent, SessionListModalComponent, SessionService, SettingsHubComponent, ShareButtonsComponent, ShareProfileModalComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, SwitchOrgModalComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TicketCardComponent, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TransferOwnershipModalComponent, TranslatePipe, TypedCollection, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_NETWORK_ERROR_KEY, VALTECH_SETTINGS_MENU_LINKS, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VERSION, ValtechErrorService, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, beautifyLegalArticle, blogPost, buildCompanyFooterProps, buildFooterLinks, buildLegalLinkResolver, buildPath, buildSettingsCards, button, collections, connectPageRefresh, createErrorStateProps, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createPermissionLabeler, createRefreshableStream, createTitleProps, docs, errorLoggingInterceptor, extractPathParams, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, iconButton, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isIonicColor, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideSplashScreen, provideValtechAboutRoutes, provideValtechAccountRoutes, provideValtechAds, provideValtechApiKeysRoutes, provideValtechAppConfig, provideValtechAppVersion, provideValtechAuth, provideValtechAuthInterceptor, provideValtechContent, provideValtechDebugConsole, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechNotificationPreferencesRoutes, provideValtechNotificationsRoutes, provideValtechOrganizationRoutes, provideValtechPermissionsRoutes, provideValtechPreferencesRoutes, provideValtechPresets, provideValtechProfileRoutes, provideValtechSecurityRoutes, provideValtechSettingsRoutes, provideValtechSite, provideValtechSkeleton, query, renderPatternSvgInner, replaceSpecialChars, resolveColor, resolveInputDefaultValue, resolveIonicColor, resolveWebBaseUrl, roleGuard, storagePaths, superAdminGuard, toArticle };
66769
+ export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AboutViewComponent, AccordionComponent, AccountViewComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimatedTerminalComponent, ApiKeyCreateModalComponent, ApiKeyService, ApiKeysModalComponent, ApiKeysViewComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentService, ContentTransformer, CookieBannerComponent, CountdownComponent, CreateOrgModalComponent, CtaCardComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_APP_VERSION_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_BUTTON_PRESETS, DEFAULT_CANCEL_BUTTON, DEFAULT_CHECK_INTERVAL_MS, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DEBUG_CONSOLE_CONFIG, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_PRESETS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DataTableComponent, DateInputComponent, DatePickerComponent, DateRangeInputComponent, DebugConsoleComponent, DeleteAccountModalComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EditOrgModalComponent, EmptyStateComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FieldListComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FontSizeOption, FontSizeService, FooterComponent, FooterLinksComponent, FormComponent, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HasPermissionDirective, HeaderComponent, HintComponent, HorizontalScrollComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, INVITATION_CARD_DEFAULTS, IONIC_COLORS$5 as IONIC_COLORS, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, InvitationCardComponent, InviteMemberModalComponent, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginAttemptModalComponent, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, METRIC_CARD_DEFAULTS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MemberCardComponent, MemberDetailModalComponent, MemberImportModalComponent, MenuComponent, MessagingService, MetaService, MetricCardComponent, MfaModalComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationPreferencesViewComponent, NotificationsService, NotificationsViewComponent, NumberFromToComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OrgInfoSheetComponent, OrgService, OrgSwitchService, OrganizationViewComponent, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PLATFORM_CONFIGS, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PermissionCatalogService, PermissionSelectorComponent, PermissionsViewComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PreferencesViewComponent, PresetService, PriceTagComponent, ProcessLinksPipe, ProfileSkeletonComponent, ProfileViewComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QrScannerComponent, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestService, RightsFooterComponent, RotatingTextComponent, SEARCH_HEADER_DEFAULTS, SETTINGS_SECTIONS_CATALOG, SHAPE_KEYS, SHARE_PROFILE_MODAL_DEFAULTS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, STATS_BAR_DEFAULTS, STROKE_KEYS, SearchHeaderComponent, SearchSelectorComponent, SearchbarComponent, SecurityViewComponent, SegmentControlComponent, SelectSearchComponent, SessionListModalComponent, SessionService, SettingsHubComponent, ShareButtonsComponent, ShareProfileModalComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, SwitchOrgModalComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TicketCardComponent, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TransferOwnershipModalComponent, TranslatePipe, TypedCollection, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_NETWORK_ERROR_KEY, VALTECH_SETTINGS_MENU_LINKS, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VERSION, ValtechErrorService, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, beautifyLegalArticle, blogPost, buildCompanyFooterProps, buildFooterLinks, buildLegalLinkResolver, buildPath, buildSettingsCards, button, collections, connectPageRefresh, createErrorStateProps, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createPageState, createPermissionLabeler, createRefreshableStream, createTitleProps, docs, errorLoggingInterceptor, extractPathParams, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, iconButton, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isIonicColor, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideSplashScreen, provideValtechAboutRoutes, provideValtechAccountRoutes, provideValtechAds, provideValtechApiKeysRoutes, provideValtechAppConfig, provideValtechAppVersion, provideValtechAuth, provideValtechAuthInterceptor, provideValtechContent, provideValtechDebugConsole, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechNotificationPreferencesRoutes, provideValtechNotificationsRoutes, provideValtechOrganizationRoutes, provideValtechPermissionsRoutes, provideValtechPreferencesRoutes, provideValtechPresets, provideValtechProfileRoutes, provideValtechSecurityRoutes, provideValtechSettingsRoutes, provideValtechSite, provideValtechSkeleton, query, renderPatternSvgInner, replaceSpecialChars, resolveColor, resolveInputDefaultValue, resolveIonicColor, resolveWebBaseUrl, roleGuard, storagePaths, superAdminGuard, toArticle };
66644
66770
  //# sourceMappingURL=valtech-components.mjs.map