valtech-components 4.0.953 → 4.0.955

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.
@@ -7,7 +7,7 @@ import { provideHttpClient, withInterceptors, HttpContextToken, HttpClient, Http
7
7
  import * as i1$1 from '@angular/fire/firestore';
8
8
  import { provideFirestore, getFirestore, connectFirestoreEmulator, enableMultiTabIndexedDbPersistence, doc, getDoc, collection, query as query$1, getDocs, getCountFromServer, limit, collectionGroup, collectionData, docData, serverTimestamp, addDoc, setDoc, updateDoc, deleteDoc, writeBatch, arrayUnion, arrayRemove, increment, where, orderBy, startAfter, startAt, endBefore, endAt, Timestamp, onSnapshot, Firestore } from '@angular/fire/firestore';
9
9
  import * as i1$4 from '@angular/common';
10
- import { isPlatformBrowser, CommonModule, NgStyle, NgFor, DOCUMENT, NgClass, TitleCasePipe, NgTemplateOutlet } from '@angular/common';
10
+ import { isPlatformBrowser, CommonModule, NgStyle, NgFor, NgClass, DOCUMENT, TitleCasePipe, NgTemplateOutlet } from '@angular/common';
11
11
  import { provideAnalytics, getAnalytics, Analytics, logEvent, setUserId, setUserProperties } from '@angular/fire/analytics';
12
12
  import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
13
13
  import * as i1 from '@angular/fire/auth';
@@ -67,7 +67,7 @@ import fixWebmDuration from 'fix-webm-duration';
67
67
  * Current version of valtech-components.
68
68
  * This is automatically updated during the publish process.
69
69
  */
70
- const VERSION = '4.0.953';
70
+ const VERSION = '4.0.955';
71
71
 
72
72
  function evaluateValtechAccess(rule, context, features = {}, visitedFeatures = new Set()) {
73
73
  if (rule == null)
@@ -22517,6 +22517,100 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
22517
22517
  type: Input
22518
22518
  }] } });
22519
22519
 
22520
+ /**
22521
+ * Layout canonico para modales con body scrolleable y footer de acciones fijo.
22522
+ *
22523
+ * Usalo dentro de componentes abiertos via `ModalService.open(...)` cuando el
22524
+ * contenido pueda crecer y el CTA deba quedar siempre visible. El header/body
22525
+ * delegan en `val-modal-shell`; el footer queda fuera del `ion-content`, como
22526
+ * sibling, para evitar problemas de scroll.
22527
+ */
22528
+ class ModalLayoutComponent {
22529
+ constructor() {
22530
+ this.title = input('');
22531
+ this.subtitle = input('');
22532
+ this.closeLabel = input('');
22533
+ this.showClose = input(true);
22534
+ this.actions = input([]);
22535
+ /**
22536
+ * Alineación del footer. **No pasarlo**: el default `auto` ya da el
22537
+ * comportamiento correcto (CTA full-width en mobile, a la derecha en desktop).
22538
+ * Ver ModalActionAlignment antes de elegir otro valor.
22539
+ */
22540
+ this.actionsAlign = input('auto');
22541
+ this.footer = input(undefined);
22542
+ this.footerClass = input('');
22543
+ this.close = output();
22544
+ this.actionClick = output();
22545
+ this.showFooter = computed(() => this.footer() ?? this.actions().length > 0);
22546
+ }
22547
+ handleAction(action, index) {
22548
+ this.actionClick.emit({ action, index });
22549
+ }
22550
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
22551
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ModalLayoutComponent, isStandalone: true, selector: "val-modal-layout", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, actionsAlign: { classPropertyName: "actionsAlign", publicName: "actionsAlign", isSignal: true, isRequired: false, transformFunction: null }, footer: { classPropertyName: "footer", publicName: "footer", isSignal: true, isRequired: false, transformFunction: null }, footerClass: { classPropertyName: "footerClass", publicName: "footerClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", actionClick: "actionClick" }, ngImport: i0, template: `
22552
+ <val-modal-shell
22553
+ [title]="title()"
22554
+ [subtitle]="subtitle()"
22555
+ [closeLabel]="closeLabel()"
22556
+ [showClose]="showClose()"
22557
+ (close)="close.emit()"
22558
+ >
22559
+ <ng-content />
22560
+ </val-modal-shell>
22561
+
22562
+ @if (showFooter()) {
22563
+ <ion-footer class="val-modal-layout__footer" [ngClass]="footerClass()">
22564
+ <div
22565
+ class="val-modal-layout__actions"
22566
+ [ngClass]="'val-modal-layout__actions--' + actionsAlign()"
22567
+ >
22568
+ @for (action of actions(); track action.token || action.text || $index) {
22569
+ <val-button
22570
+ class="val-modal-layout__button"
22571
+ [props]="action"
22572
+ (onClick)="handleAction(action, $index)"
22573
+ />
22574
+ }
22575
+ <ng-content select="[modal-actions]" />
22576
+ </div>
22577
+ </ion-footer>
22578
+ }
22579
+ `, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;min-height:0}.val-modal-layout__footer{flex-shrink:0;background:var( --ion-card-background, var(--ion-background-color, #fff) );border-top:1px solid var(--ion-border-color, #e7e4ea)}.val-modal-layout__actions{display:flex;align-items:center;gap:var(--val-modal-footer-gap, 8px);padding:var(--val-modal-footer-padding, 12px 16px);padding-bottom:calc(var(--val-modal-footer-padding-bottom, 12px) + var(--ion-safe-area-bottom, env(safe-area-inset-bottom, 0px)))}.val-modal-layout__actions--start{justify-content:flex-start}.val-modal-layout__actions--center{justify-content:center}.val-modal-layout__actions--end{justify-content:flex-end}.val-modal-layout__actions--space-between{justify-content:space-between}.val-modal-layout__actions--auto,.val-modal-layout__actions--stretch{justify-content:flex-end}.val-modal-layout__actions--auto .val-modal-layout__button,.val-modal-layout__actions--stretch .val-modal-layout__button{flex:1 1 auto;min-width:0;display:block}.val-modal-layout__actions--auto .val-modal-layout__button ::ng-deep ion-button,.val-modal-layout__actions--stretch .val-modal-layout__button ::ng-deep ion-button{width:100%}@media (min-width: 481px){.val-modal-layout__actions--auto .val-modal-layout__button,.val-modal-layout__actions--stretch .val-modal-layout__button{flex:0 0 auto;display:inline-block}.val-modal-layout__actions--auto .val-modal-layout__button ::ng-deep ion-button,.val-modal-layout__actions--stretch .val-modal-layout__button ::ng-deep ion-button{width:auto}}@media (max-width: 480px){.val-modal-layout__actions{padding-left:var(--val-modal-footer-padding-inline-mobile, 16px);padding-right:var(--val-modal-footer-padding-inline-mobile, 16px)}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: ModalShellComponent, selector: "val-modal-shell", inputs: ["title", "subtitle", "closeLabel", "showClose"], outputs: ["close"] }] }); }
22580
+ }
22581
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalLayoutComponent, decorators: [{
22582
+ type: Component,
22583
+ args: [{ selector: 'val-modal-layout', standalone: true, imports: [NgClass, IonFooter, ButtonComponent, ModalShellComponent], template: `
22584
+ <val-modal-shell
22585
+ [title]="title()"
22586
+ [subtitle]="subtitle()"
22587
+ [closeLabel]="closeLabel()"
22588
+ [showClose]="showClose()"
22589
+ (close)="close.emit()"
22590
+ >
22591
+ <ng-content />
22592
+ </val-modal-shell>
22593
+
22594
+ @if (showFooter()) {
22595
+ <ion-footer class="val-modal-layout__footer" [ngClass]="footerClass()">
22596
+ <div
22597
+ class="val-modal-layout__actions"
22598
+ [ngClass]="'val-modal-layout__actions--' + actionsAlign()"
22599
+ >
22600
+ @for (action of actions(); track action.token || action.text || $index) {
22601
+ <val-button
22602
+ class="val-modal-layout__button"
22603
+ [props]="action"
22604
+ (onClick)="handleAction(action, $index)"
22605
+ />
22606
+ }
22607
+ <ng-content select="[modal-actions]" />
22608
+ </div>
22609
+ </ion-footer>
22610
+ }
22611
+ `, styles: [":host{display:flex;flex-direction:column;height:100%;min-height:0}.val-modal-layout__footer{flex-shrink:0;background:var( --ion-card-background, var(--ion-background-color, #fff) );border-top:1px solid var(--ion-border-color, #e7e4ea)}.val-modal-layout__actions{display:flex;align-items:center;gap:var(--val-modal-footer-gap, 8px);padding:var(--val-modal-footer-padding, 12px 16px);padding-bottom:calc(var(--val-modal-footer-padding-bottom, 12px) + var(--ion-safe-area-bottom, env(safe-area-inset-bottom, 0px)))}.val-modal-layout__actions--start{justify-content:flex-start}.val-modal-layout__actions--center{justify-content:center}.val-modal-layout__actions--end{justify-content:flex-end}.val-modal-layout__actions--space-between{justify-content:space-between}.val-modal-layout__actions--auto,.val-modal-layout__actions--stretch{justify-content:flex-end}.val-modal-layout__actions--auto .val-modal-layout__button,.val-modal-layout__actions--stretch .val-modal-layout__button{flex:1 1 auto;min-width:0;display:block}.val-modal-layout__actions--auto .val-modal-layout__button ::ng-deep ion-button,.val-modal-layout__actions--stretch .val-modal-layout__button ::ng-deep ion-button{width:100%}@media (min-width: 481px){.val-modal-layout__actions--auto .val-modal-layout__button,.val-modal-layout__actions--stretch .val-modal-layout__button{flex:0 0 auto;display:inline-block}.val-modal-layout__actions--auto .val-modal-layout__button ::ng-deep ion-button,.val-modal-layout__actions--stretch .val-modal-layout__button ::ng-deep ion-button{width:auto}}@media (max-width: 480px){.val-modal-layout__actions{padding-left:var(--val-modal-footer-padding-inline-mobile, 16px);padding-right:var(--val-modal-footer-padding-inline-mobile, 16px)}}\n"] }]
22612
+ }] });
22613
+
22520
22614
  /**
22521
22615
  * Removes diacritical marks (accents) from a string using Unicode normalization.
22522
22616
  * Useful for text search and comparison.
@@ -22529,6 +22623,152 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
22529
22623
  */
22530
22624
  const replaceSpecialChars = (text) => text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
22531
22625
 
22626
+ /**
22627
+ * Picker de `val-select-search` / `val-multi-select-search` — full-screen en
22628
+ * mobile, card flotante en desktop (`ModalService.openAdaptive`, Regla #5).
22629
+ * Reemplaza el `ion-modal` con breakpoints que ambos componentes tenían
22630
+ * embebido: mismo bottom-sheet en cualquier tamaño de pantalla, sin el
22631
+ * tratamiento "card centrada" que el resto de los modales del factory ya usa.
22632
+ *
22633
+ * Selección simple: cierra al tocar un ítem (`dismiss({values:[v]}, 'selected')`).
22634
+ * Selección múltiple: acumula localmente, footer con "Aplicar" (Regla #5,
22635
+ * val-modal-layout con `actions`).
22636
+ */
22637
+ class SelectSearchPickerModalComponent {
22638
+ constructor() {
22639
+ this.i18n = inject(I18nService);
22640
+ this.query = signal('');
22641
+ this.selected = signal([]);
22642
+ this.filteredItems = computed(() => {
22643
+ this.ensureSeeded();
22644
+ const opts = this.props.options ?? [];
22645
+ const q = replaceSpecialChars(this.query().trim().toLowerCase());
22646
+ if (!q)
22647
+ return opts;
22648
+ return opts.filter(o => {
22649
+ const label = replaceSpecialChars(String(o[this.props.labelProperty] ?? '').toLowerCase());
22650
+ const value = replaceSpecialChars(String(o[this.props.valueProperty] ?? '').toLowerCase());
22651
+ return label.includes(q) || value.includes(q);
22652
+ });
22653
+ });
22654
+ this.footerActions = computed(() => this.props?.multiple
22655
+ ? [
22656
+ {
22657
+ text: this.i18n.t('apply'),
22658
+ color: 'primary',
22659
+ shape: 'round',
22660
+ type: 'button',
22661
+ state: 'ENABLED',
22662
+ },
22663
+ ]
22664
+ : []);
22665
+ // `props` llega por componentProps (Ionic hace el assign DESPUÉS de construir
22666
+ // la instancia, no en el constructor) — sembrar la selección tiene que pasar
22667
+ // en el primer acceso desde el template, no acá. Un flag propio en vez de
22668
+ // "selected().length === 0": si el usuario deselecciona todo a propósito, un
22669
+ // chequeo por longitud volvería a sembrar los valores originales en la
22670
+ // siguiente change-detection.
22671
+ this.seeded = false;
22672
+ }
22673
+ ensureSeeded() {
22674
+ if (this.seeded)
22675
+ return;
22676
+ this.seeded = true;
22677
+ if (this.props?.selectedValues?.length) {
22678
+ this.selected.set([...this.props.selectedValues]);
22679
+ }
22680
+ }
22681
+ isSelected(item) {
22682
+ this.ensureSeeded();
22683
+ return this.selected().includes(item[this.props.valueProperty]);
22684
+ }
22685
+ toggle(item) {
22686
+ this.ensureSeeded();
22687
+ const value = item[this.props.valueProperty];
22688
+ if (!this.props.multiple) {
22689
+ this._modalRef?.dismiss({ values: [value] }, 'selected');
22690
+ return;
22691
+ }
22692
+ const current = this.selected();
22693
+ const idx = current.indexOf(value);
22694
+ this.selected.set(idx === -1 ? [...current, value] : current.filter(v => v !== value));
22695
+ }
22696
+ apply() {
22697
+ this._modalRef?.dismiss({ values: this.selected() }, 'selected');
22698
+ }
22699
+ cancel() {
22700
+ this._modalRef?.dismiss(undefined, 'cancel');
22701
+ }
22702
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectSearchPickerModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
22703
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SelectSearchPickerModalComponent, isStandalone: true, selector: "val-select-search-picker-modal", ngImport: i0, template: `
22704
+ <val-modal-layout
22705
+ [title]="props.title"
22706
+ [closeLabel]="i18n.t('close')"
22707
+ [actions]="footerActions()"
22708
+ actionsAlign="stretch"
22709
+ (close)="cancel()"
22710
+ (actionClick)="apply()"
22711
+ >
22712
+ <div class="ssp-search">
22713
+ <val-searchbar
22714
+ [props]="{ placeholder: props.placeholder || i18n.t('selectOption'), debounce: 200 }"
22715
+ (filterEvent)="query.set($event)"
22716
+ />
22717
+ </div>
22718
+
22719
+ @if (filteredItems().length === 0) {
22720
+ <p class="ssp-empty">{{ i18n.t('noResults') }}</p>
22721
+ } @else {
22722
+ <ion-list class="ssp-list" lines="none">
22723
+ @for (item of filteredItems(); track item[props.valueProperty]) {
22724
+ <ion-item class="ssp-item" button detail="false" (click)="toggle(item)">
22725
+ <ion-label>{{ item[props.labelProperty] }}</ion-label>
22726
+ @if (isSelected(item)) {
22727
+ <ion-icon name="checkmark-outline" slot="end" color="primary" aria-hidden="true" />
22728
+ }
22729
+ </ion-item>
22730
+ }
22731
+ </ion-list>
22732
+ }
22733
+ </val-modal-layout>
22734
+ `, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;min-height:0}.ssp-search{margin:0 0 12px}.ssp-list{background:transparent;display:flex;flex-direction:column;gap:6px}.ssp-item{--background: var(--ion-card-background, var(--ion-background-color, #fff));--padding-start: 12px;--padding-end: 12px;--inner-padding-end: 0;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:10px;cursor:pointer}.ssp-empty{text-align:center;color:var(--ion-color-medium, #92949c);font-size:.875rem;margin:24px 0}\n"], dependencies: [{ kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: ModalLayoutComponent, selector: "val-modal-layout", inputs: ["title", "subtitle", "closeLabel", "showClose", "actions", "actionsAlign", "footer", "footerClass"], outputs: ["close", "actionClick"] }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["preset", "props"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }] }); }
22735
+ }
22736
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectSearchPickerModalComponent, decorators: [{
22737
+ type: Component,
22738
+ args: [{ selector: 'val-select-search-picker-modal', standalone: true, imports: [IonIcon, IonItem, IonLabel, IonList, ButtonComponent, ModalLayoutComponent, SearchbarComponent], template: `
22739
+ <val-modal-layout
22740
+ [title]="props.title"
22741
+ [closeLabel]="i18n.t('close')"
22742
+ [actions]="footerActions()"
22743
+ actionsAlign="stretch"
22744
+ (close)="cancel()"
22745
+ (actionClick)="apply()"
22746
+ >
22747
+ <div class="ssp-search">
22748
+ <val-searchbar
22749
+ [props]="{ placeholder: props.placeholder || i18n.t('selectOption'), debounce: 200 }"
22750
+ (filterEvent)="query.set($event)"
22751
+ />
22752
+ </div>
22753
+
22754
+ @if (filteredItems().length === 0) {
22755
+ <p class="ssp-empty">{{ i18n.t('noResults') }}</p>
22756
+ } @else {
22757
+ <ion-list class="ssp-list" lines="none">
22758
+ @for (item of filteredItems(); track item[props.valueProperty]) {
22759
+ <ion-item class="ssp-item" button detail="false" (click)="toggle(item)">
22760
+ <ion-label>{{ item[props.labelProperty] }}</ion-label>
22761
+ @if (isSelected(item)) {
22762
+ <ion-icon name="checkmark-outline" slot="end" color="primary" aria-hidden="true" />
22763
+ }
22764
+ </ion-item>
22765
+ }
22766
+ </ion-list>
22767
+ }
22768
+ </val-modal-layout>
22769
+ `, styles: [":host{display:flex;flex-direction:column;height:100%;min-height:0}.ssp-search{margin:0 0 12px}.ssp-list{background:transparent;display:flex;flex-direction:column;gap:6px}.ssp-item{--background: var(--ion-card-background, var(--ion-background-color, #fff));--padding-start: 12px;--padding-end: 12px;--inner-padding-end: 0;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:10px;cursor:pointer}.ssp-empty{text-align:center;color:var(--ion-color-medium, #92949c);font-size:.875rem;margin:24px 0}\n"] }]
22770
+ }] });
22771
+
22532
22772
  /**
22533
22773
  * val-select-search
22534
22774
  *
@@ -22549,6 +22789,7 @@ class SelectSearchComponent {
22549
22789
  this.icon = inject(IconService);
22550
22790
  this.changeDetector = inject(ChangeDetectorRef);
22551
22791
  this.i18n = inject(I18nService);
22792
+ this.modals = inject(ModalService);
22552
22793
  this.searchTerm = '';
22553
22794
  this.filteredItems = [];
22554
22795
  this.selectedItems = [];
@@ -22714,90 +22955,43 @@ class SelectSearchComponent {
22714
22955
  applyDefaultValue() {
22715
22956
  applyDefaultValueToControl(this.props);
22716
22957
  }
22717
- onFilter(event) {
22718
- // If no search term, show all options
22719
- if (!event || event.trim() === '') {
22720
- this.filteredItems = this.props?.options ? [...this.props.options] : [];
22721
- this.changeDetector.detectChanges();
22722
- return;
22723
- }
22724
- // If no options, nothing to filter
22725
- if (!this.props?.options || this.props.options.length === 0) {
22726
- this.filteredItems = [];
22727
- this.changeDetector.detectChanges();
22728
- return;
22729
- }
22730
- // PERF: Avoid repeated replaceSpecialChars and toLowerCase for each option
22731
- const search = replaceSpecialChars(event.toLowerCase());
22732
- this.filteredItems = this.props.options.filter(element => {
22733
- // Only use labelProperty and valueProperty for filtering (faster)
22734
- const label = element[this.labelProperty]
22735
- ? replaceSpecialChars(String(element[this.labelProperty]).toLowerCase())
22736
- : '';
22737
- const value = element[this.valueProperty]
22738
- ? replaceSpecialChars(String(element[this.valueProperty]).toLowerCase())
22739
- : '';
22740
- return label.includes(search) || value.includes(search);
22741
- });
22742
- this.changeDetector.detectChanges();
22743
- }
22744
- onFocus() {
22745
- console.log('onFocus');
22746
- }
22747
- onBlur() {
22748
- console.log('onBlur');
22749
- }
22750
- openModal() {
22751
- if (this.modal) {
22752
- this.modal.present();
22753
- }
22754
- }
22755
- preventDefaultBehavior(event) {
22756
- event.preventDefault();
22757
- event.stopPropagation();
22758
- this.openModal();
22759
- }
22760
- /**
22761
- * Reset state only - called by didDismiss event
22762
- * Separated from closeModal to avoid double dismissal and scroll issues
22763
- */
22764
- resetState() {
22765
- this.searchTerm = '';
22766
- this.filteredItems = this.props?.options ? [...this.props.options] : [];
22767
- }
22768
22958
  /**
22769
- * Close modal only - does not reset state (didDismiss will handle that)
22959
+ * Abre el picker vía `ModalService.openAdaptive` (Regla #5: full-screen en
22960
+ * mobile, card flotante en desktop) en vez del `ion-modal` con breakpoints
22961
+ * que este componente tenía embebido antes — mismo bottom-sheet en
22962
+ * cualquier tamaño de pantalla, sin el tratamiento de card centrada que ya
22963
+ * usa el resto de los modales del factory. El filtrado, la selección y el
22964
+ * footer "Aplicar" (modo `multiple`) viven en `SelectSearchPickerModalComponent`.
22770
22965
  */
22771
- closeModal() {
22772
- if (this.modal) {
22773
- this.modal.dismiss();
22774
- }
22775
- }
22776
- /**
22777
- * @deprecated Use closeModal() instead. Kept for backwards compatibility.
22778
- */
22779
- cancelModal() {
22780
- this.closeModal();
22781
- }
22782
- selectItem(item) {
22783
- if (this.multiple) {
22784
- const index = this.selectedItems.findIndex(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
22785
- if (index === -1) {
22786
- this.selectedItems.push(item);
22787
- }
22788
- else {
22789
- this.selectedItems.splice(index, 1);
22790
- }
22791
- }
22792
- else {
22793
- this.selectedItems = [item];
22794
- this.closeModal();
22795
- }
22966
+ async openPicker() {
22967
+ const { data, role } = await this.modals.openAdaptive({
22968
+ component: SelectSearchPickerModalComponent,
22969
+ componentProps: {
22970
+ props: {
22971
+ title: this.getLabel(),
22972
+ options: this.props?.options ?? [],
22973
+ valueProperty: this.valueProperty,
22974
+ labelProperty: this.labelProperty,
22975
+ multiple: this.multiple,
22976
+ selectedValues: this.selectedItems.map(item => item[this.valueProperty]),
22977
+ placeholder: this.getPlaceholder(),
22978
+ },
22979
+ },
22980
+ });
22981
+ if (role !== 'selected' || !data)
22982
+ return;
22983
+ const values = data.values ?? [];
22984
+ const options = this.props?.options ?? [];
22985
+ this.selectedItems = values
22986
+ .map(v => options.find(o => o[this.valueProperty] === v))
22987
+ .filter((o) => !!o);
22796
22988
  this.updateDisplayValue();
22797
22989
  this.applyChanges();
22798
22990
  }
22799
- isItemSelected(item) {
22800
- return this.selectedItems.some(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
22991
+ preventDefaultBehavior(event) {
22992
+ event.preventDefault();
22993
+ event.stopPropagation();
22994
+ void this.openPicker();
22801
22995
  }
22802
22996
  updateDisplayValue() {
22803
22997
  if (this.props?.mode === 'legacy' && this.selectedItems.length === 0 && this.props?.control?.value) {
@@ -22849,7 +23043,7 @@ class SelectSearchComponent {
22849
23043
  this.changeDetector.detectChanges();
22850
23044
  }
22851
23045
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
22852
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SelectSearchComponent, isStandalone: true, selector: "val-select-search", inputs: { label: "label", labelProperty: "labelProperty", valueProperty: "valueProperty", multiple: "multiple", placeholder: "placeholder", props: "props" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
23046
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SelectSearchComponent, isStandalone: true, selector: "val-select-search", inputs: { label: "label", labelProperty: "labelProperty", valueProperty: "valueProperty", multiple: "multiple", placeholder: "placeholder", props: "props" }, usesOnChanges: true, ngImport: i0, template: `
22853
23047
  <label *ngIf="displayLabel" class="vss-label">{{ displayLabel }}</label>
22854
23048
 
22855
23049
  <ion-input
@@ -22861,44 +23055,11 @@ class SelectSearchComponent {
22861
23055
  />
22862
23056
 
22863
23057
  <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
22864
-
22865
- <ion-modal #modal [initialBreakpoint]="1" [breakpoints]="[0, 0.5, 0.75, 1]" (didDismiss)="resetState()">
22866
- <ng-template>
22867
- <ion-header>
22868
- <ion-toolbar>
22869
- <ion-title>{{ getLabel() }}</ion-title>
22870
- <ion-buttons slot="end">
22871
- <ion-button (click)="cancelModal()">{{ getCloseText() }}</ion-button>
22872
- </ion-buttons>
22873
- </ion-toolbar>
22874
- <ion-toolbar>
22875
- <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
22876
- </ion-toolbar>
22877
- </ion-header>
22878
- <ion-content>
22879
- <ion-list>
22880
- <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
22881
- <ion-label>{{ item[labelProperty] }}</ion-label>
22882
- <ion-icon
22883
- *ngIf="isItemSelected(item)"
22884
- name="checkmark-outline"
22885
- slot="end"
22886
- color="primary"
22887
- aria-hidden="true"
22888
- ></ion-icon>
22889
- </ion-item>
22890
- <ion-item *ngIf="filteredItems.length === 0" lines="none">
22891
- <ion-label color="dark">{{ getNoResultsText() }}</ion-label>
22892
- </ion-item>
22893
- </ion-list>
22894
- </ion-content>
22895
- </ng-template>
22896
- </ion-modal>
22897
- `, isInline: true, styles: [":host{display:block}.vss-label{display:block;margin-bottom:4px;font-size:.8125rem;color:var(--ion-color-dark, #43464d)}ion-header{padding:8px 8px 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.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: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearInputIcon", "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", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonModal, selector: "ion-modal" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-input-otp[type=text],ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["preset", "props"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$8.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
23058
+ `, isInline: true, styles: [":host{display:block}.vss-label{display:block;margin-bottom:4px;font-size:.8125rem;color:var(--ion-color-dark, #43464d)}ion-header{padding:8px 8px 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearInputIcon", "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", "spellcheck", "step", "type", "value"] }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-input-otp[type=text],ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$8.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
22898
23059
  }
22899
23060
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectSearchComponent, decorators: [{
22900
23061
  type: Component,
22901
- args: [{ selector: 'val-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, SearchbarComponent, ReactiveFormsModule], template: `
23062
+ args: [{ selector: 'val-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, ReactiveFormsModule], template: `
22902
23063
  <label *ngIf="displayLabel" class="vss-label">{{ displayLabel }}</label>
22903
23064
 
22904
23065
  <ion-input
@@ -22910,44 +23071,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
22910
23071
  />
22911
23072
 
22912
23073
  <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
22913
-
22914
- <ion-modal #modal [initialBreakpoint]="1" [breakpoints]="[0, 0.5, 0.75, 1]" (didDismiss)="resetState()">
22915
- <ng-template>
22916
- <ion-header>
22917
- <ion-toolbar>
22918
- <ion-title>{{ getLabel() }}</ion-title>
22919
- <ion-buttons slot="end">
22920
- <ion-button (click)="cancelModal()">{{ getCloseText() }}</ion-button>
22921
- </ion-buttons>
22922
- </ion-toolbar>
22923
- <ion-toolbar>
22924
- <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
22925
- </ion-toolbar>
22926
- </ion-header>
22927
- <ion-content>
22928
- <ion-list>
22929
- <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
22930
- <ion-label>{{ item[labelProperty] }}</ion-label>
22931
- <ion-icon
22932
- *ngIf="isItemSelected(item)"
22933
- name="checkmark-outline"
22934
- slot="end"
22935
- color="primary"
22936
- aria-hidden="true"
22937
- ></ion-icon>
22938
- </ion-item>
22939
- <ion-item *ngIf="filteredItems.length === 0" lines="none">
22940
- <ion-label color="dark">{{ getNoResultsText() }}</ion-label>
22941
- </ion-item>
22942
- </ion-list>
22943
- </ion-content>
22944
- </ng-template>
22945
- </ion-modal>
22946
23074
  `, styles: [":host{display:block}.vss-label{display:block;margin-bottom:4px;font-size:.8125rem;color:var(--ion-color-dark, #43464d)}ion-header{padding:8px 8px 0}\n"] }]
22947
- }], propDecorators: { modal: [{
22948
- type: ViewChild,
22949
- args: ['modal']
22950
- }], label: [{
23075
+ }], propDecorators: { label: [{
22951
23076
  type: Input
22952
23077
  }], labelProperty: [{
22953
23078
  type: Input
@@ -33127,23 +33252,13 @@ class MetadataListComponent {
33127
33252
  });
33128
33253
  this.hostClass = computed(() => {
33129
33254
  const p = this.resolvedProps();
33130
- return [
33131
- 'ml',
33132
- p.dividers ? 'ml--dividers' : '',
33133
- p.size === 'small' ? 'ml--small' : '',
33134
- (p.columns ?? 1) > 1 ? 'ml--grid' : '',
33135
- ]
33136
- .filter(Boolean)
33137
- .join(' ');
33138
- });
33139
- this.gridStyle = computed(() => {
33140
- const cols = this.resolvedProps().columns ?? 1;
33141
- return cols > 1 ? `repeat(${cols}, 1fr)` : null;
33255
+ return ['ml', p.dividers ? 'ml--dividers' : '', p.size === 'small' ? 'ml--small' : ''].filter(Boolean).join(' ');
33142
33256
  });
33257
+ this.gridStyle = computed(() => null);
33143
33258
  }
33144
33259
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MetadataListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33145
33260
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MetadataListComponent, isStandalone: true, selector: "val-metadata-list", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
33146
- <dl [class]="hostClass()" [style.grid-template-columns]="gridStyle()">
33261
+ <dl [class]="hostClass()">
33147
33262
  @for (section of resolvedSections(); track $index) {
33148
33263
  @if (section.label) {
33149
33264
  <div class="ml__section-label">{{ section.label }}</div>
@@ -33179,12 +33294,12 @@ class MetadataListComponent {
33179
33294
  }
33180
33295
  }
33181
33296
  </dl>
33182
- `, isInline: true, styles: ["@charset \"UTF-8\";:host{display:block}.ml{display:flex;flex-direction:column}.ml--dividers .ml__row:not(:last-child){border-bottom:1px solid var(--ion-border-color, rgba(0, 0, 0, .08))}.ml--grid{display:grid}.ml__section-label{grid-column:1/-1;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--ion-color-medium, #92949c);padding-top:20px;padding-bottom:4px}.ml__section-label:first-child{padding-top:0}.ml--small .ml__section-label{font-size:.625rem;padding-top:16px}.ml__row--chips{grid-column:1/-1}.ml__row{display:flex;align-items:flex-start;gap:10px;padding:8px 0;grid-column:1/-1}.ml--small .ml__row{padding:5px 0}.ml__item{display:flex;align-items:flex-start;gap:10px;padding:8px 0}.ml--small .ml__item{padding:5px 0}.ml__icon{flex-shrink:0;font-size:1.125rem;color:var(--ion-color-medium, #92949c);line-height:1;margin-top:1px;padding:5px 0}.ml--grid .ml__icon{padding:5px 0}.ml--small .ml__icon{font-size:1rem}.ml__icon--placeholder{width:1.125rem;height:1.125rem}.ml--small .ml__icon--placeholder{width:1rem;height:1rem}.ml__text{display:flex;flex-direction:column;gap:2px;min-width:0}.ml__cell{display:flex;flex-direction:column;gap:2px;min-width:0;padding:5px 0}.ml--grid .ml__cell{padding:5px 0}.ml__label{font-size:.6875rem;font-weight:500;text-transform:uppercase;letter-spacing:.04em;color:var(--ion-color-medium, #92949c);line-height:1.3}.ml--small .ml__label{font-size:.625rem}.ml__value{font-size:.875rem;font-weight:600;color:var(--ion-text-color, #000);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ml--small .ml__value{font-size:.8125rem}.ml__chips{display:flex;flex-wrap:wrap;gap:4px;margin:0;padding:0}.ml__chip{display:inline-block;font-size:.75rem;font-weight:500;line-height:1;padding:3px 8px;border-radius:100px;background:var(--ion-color-light, rgba(0, 0, 0, .06));color:var(--ion-text-color, #000)}.ml--small .ml__chip{font-size:.6875rem;padding:2px 7px}\n"], dependencies: [{ kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
33297
+ `, isInline: true, styles: ["@charset \"UTF-8\";:host{display:block}.ml{display:flex;flex-direction:column}.ml--dividers .ml__item:not(:last-child),.ml--dividers .ml__row:not(:last-child){border-bottom:1px solid var(--ion-border-color, rgba(0, 0, 0, .08))}.ml__section-label{font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--ion-color-medium, #92949c);padding-top:20px;padding-bottom:4px}.ml__section-label:first-child{padding-top:0}.ml--small .ml__section-label{font-size:.625rem;padding-top:16px}.ml__row{display:flex;align-items:flex-start;gap:10px;padding:8px 0;grid-column:1/-1}.ml--small .ml__row{padding:5px 0}.ml__item{display:flex;align-items:flex-start;gap:10px;padding:12px 0;width:100%}.ml--small .ml__item{padding:8px 0}.ml__icon{flex-shrink:0;font-size:1.125rem;color:var(--ion-color-medium, #92949c);line-height:1;margin-top:1px;padding:5px 0}.ml--grid .ml__icon{padding:5px 0}.ml--small .ml__icon{font-size:1rem}.ml__icon--placeholder{width:1.125rem;height:1.125rem}.ml--small .ml__icon--placeholder{width:1rem;height:1rem}.ml__text{display:flex;flex-direction:column;gap:2px;min-width:0}.ml__cell{display:flex;flex-direction:column;gap:2px;min-width:0;padding:5px 0}.ml--grid .ml__cell{padding:5px 0}.ml__label{font-size:.6875rem;font-weight:500;text-transform:uppercase;letter-spacing:.04em;color:var(--ion-color-medium, #92949c);line-height:1.3}.ml--small .ml__label{font-size:.625rem}.ml__value{font-size:.875rem;font-weight:600;color:var(--ion-text-color, #000);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ml--small .ml__value{font-size:.8125rem}.ml__chips{display:flex;flex-wrap:wrap;gap:4px;margin:0;padding:0}.ml__chip{display:inline-block;font-size:.75rem;font-weight:500;line-height:1;padding:3px 8px;border-radius:100px;background:var(--ion-color-light, rgba(0, 0, 0, .06));color:var(--ion-text-color, #000)}.ml--small .ml__chip{font-size:.6875rem;padding:2px 7px}\n"], dependencies: [{ kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
33183
33298
  }
33184
33299
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MetadataListComponent, decorators: [{
33185
33300
  type: Component,
33186
33301
  args: [{ selector: 'val-metadata-list', standalone: true, imports: [IonIcon], template: `
33187
- <dl [class]="hostClass()" [style.grid-template-columns]="gridStyle()">
33302
+ <dl [class]="hostClass()">
33188
33303
  @for (section of resolvedSections(); track $index) {
33189
33304
  @if (section.label) {
33190
33305
  <div class="ml__section-label">{{ section.label }}</div>
@@ -33220,7 +33335,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
33220
33335
  }
33221
33336
  }
33222
33337
  </dl>
33223
- `, styles: ["@charset \"UTF-8\";:host{display:block}.ml{display:flex;flex-direction:column}.ml--dividers .ml__row:not(:last-child){border-bottom:1px solid var(--ion-border-color, rgba(0, 0, 0, .08))}.ml--grid{display:grid}.ml__section-label{grid-column:1/-1;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--ion-color-medium, #92949c);padding-top:20px;padding-bottom:4px}.ml__section-label:first-child{padding-top:0}.ml--small .ml__section-label{font-size:.625rem;padding-top:16px}.ml__row--chips{grid-column:1/-1}.ml__row{display:flex;align-items:flex-start;gap:10px;padding:8px 0;grid-column:1/-1}.ml--small .ml__row{padding:5px 0}.ml__item{display:flex;align-items:flex-start;gap:10px;padding:8px 0}.ml--small .ml__item{padding:5px 0}.ml__icon{flex-shrink:0;font-size:1.125rem;color:var(--ion-color-medium, #92949c);line-height:1;margin-top:1px;padding:5px 0}.ml--grid .ml__icon{padding:5px 0}.ml--small .ml__icon{font-size:1rem}.ml__icon--placeholder{width:1.125rem;height:1.125rem}.ml--small .ml__icon--placeholder{width:1rem;height:1rem}.ml__text{display:flex;flex-direction:column;gap:2px;min-width:0}.ml__cell{display:flex;flex-direction:column;gap:2px;min-width:0;padding:5px 0}.ml--grid .ml__cell{padding:5px 0}.ml__label{font-size:.6875rem;font-weight:500;text-transform:uppercase;letter-spacing:.04em;color:var(--ion-color-medium, #92949c);line-height:1.3}.ml--small .ml__label{font-size:.625rem}.ml__value{font-size:.875rem;font-weight:600;color:var(--ion-text-color, #000);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ml--small .ml__value{font-size:.8125rem}.ml__chips{display:flex;flex-wrap:wrap;gap:4px;margin:0;padding:0}.ml__chip{display:inline-block;font-size:.75rem;font-weight:500;line-height:1;padding:3px 8px;border-radius:100px;background:var(--ion-color-light, rgba(0, 0, 0, .06));color:var(--ion-text-color, #000)}.ml--small .ml__chip{font-size:.6875rem;padding:2px 7px}\n"] }]
33338
+ `, styles: ["@charset \"UTF-8\";:host{display:block}.ml{display:flex;flex-direction:column}.ml--dividers .ml__item:not(:last-child),.ml--dividers .ml__row:not(:last-child){border-bottom:1px solid var(--ion-border-color, rgba(0, 0, 0, .08))}.ml__section-label{font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--ion-color-medium, #92949c);padding-top:20px;padding-bottom:4px}.ml__section-label:first-child{padding-top:0}.ml--small .ml__section-label{font-size:.625rem;padding-top:16px}.ml__row{display:flex;align-items:flex-start;gap:10px;padding:8px 0;grid-column:1/-1}.ml--small .ml__row{padding:5px 0}.ml__item{display:flex;align-items:flex-start;gap:10px;padding:12px 0;width:100%}.ml--small .ml__item{padding:8px 0}.ml__icon{flex-shrink:0;font-size:1.125rem;color:var(--ion-color-medium, #92949c);line-height:1;margin-top:1px;padding:5px 0}.ml--grid .ml__icon{padding:5px 0}.ml--small .ml__icon{font-size:1rem}.ml__icon--placeholder{width:1.125rem;height:1.125rem}.ml--small .ml__icon--placeholder{width:1rem;height:1rem}.ml__text{display:flex;flex-direction:column;gap:2px;min-width:0}.ml__cell{display:flex;flex-direction:column;gap:2px;min-width:0;padding:5px 0}.ml--grid .ml__cell{padding:5px 0}.ml__label{font-size:.6875rem;font-weight:500;text-transform:uppercase;letter-spacing:.04em;color:var(--ion-color-medium, #92949c);line-height:1.3}.ml--small .ml__label{font-size:.625rem}.ml__value{font-size:.875rem;font-weight:600;color:var(--ion-text-color, #000);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ml--small .ml__value{font-size:.8125rem}.ml__chips{display:flex;flex-wrap:wrap;gap:4px;margin:0;padding:0}.ml__chip{display:inline-block;font-size:.75rem;font-weight:500;line-height:1;padding:3px 8px;border-radius:100px;background:var(--ion-color-light, rgba(0, 0, 0, .06));color:var(--ion-text-color, #000)}.ml--small .ml__chip{font-size:.6875rem;padding:2px 7px}\n"] }]
33224
33339
  }] });
33225
33340
 
33226
33341
  /**
@@ -38478,100 +38593,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
38478
38593
  type: Output
38479
38594
  }] } });
38480
38595
 
38481
- /**
38482
- * Layout canonico para modales con body scrolleable y footer de acciones fijo.
38483
- *
38484
- * Usalo dentro de componentes abiertos via `ModalService.open(...)` cuando el
38485
- * contenido pueda crecer y el CTA deba quedar siempre visible. El header/body
38486
- * delegan en `val-modal-shell`; el footer queda fuera del `ion-content`, como
38487
- * sibling, para evitar problemas de scroll.
38488
- */
38489
- class ModalLayoutComponent {
38490
- constructor() {
38491
- this.title = input('');
38492
- this.subtitle = input('');
38493
- this.closeLabel = input('');
38494
- this.showClose = input(true);
38495
- this.actions = input([]);
38496
- /**
38497
- * Alineación del footer. **No pasarlo**: el default `auto` ya da el
38498
- * comportamiento correcto (CTA full-width en mobile, a la derecha en desktop).
38499
- * Ver ModalActionAlignment antes de elegir otro valor.
38500
- */
38501
- this.actionsAlign = input('auto');
38502
- this.footer = input(undefined);
38503
- this.footerClass = input('');
38504
- this.close = output();
38505
- this.actionClick = output();
38506
- this.showFooter = computed(() => this.footer() ?? this.actions().length > 0);
38507
- }
38508
- handleAction(action, index) {
38509
- this.actionClick.emit({ action, index });
38510
- }
38511
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
38512
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ModalLayoutComponent, isStandalone: true, selector: "val-modal-layout", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, actionsAlign: { classPropertyName: "actionsAlign", publicName: "actionsAlign", isSignal: true, isRequired: false, transformFunction: null }, footer: { classPropertyName: "footer", publicName: "footer", isSignal: true, isRequired: false, transformFunction: null }, footerClass: { classPropertyName: "footerClass", publicName: "footerClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", actionClick: "actionClick" }, ngImport: i0, template: `
38513
- <val-modal-shell
38514
- [title]="title()"
38515
- [subtitle]="subtitle()"
38516
- [closeLabel]="closeLabel()"
38517
- [showClose]="showClose()"
38518
- (close)="close.emit()"
38519
- >
38520
- <ng-content />
38521
- </val-modal-shell>
38522
-
38523
- @if (showFooter()) {
38524
- <ion-footer class="val-modal-layout__footer" [ngClass]="footerClass()">
38525
- <div
38526
- class="val-modal-layout__actions"
38527
- [ngClass]="'val-modal-layout__actions--' + actionsAlign()"
38528
- >
38529
- @for (action of actions(); track action.token || action.text || $index) {
38530
- <val-button
38531
- class="val-modal-layout__button"
38532
- [props]="action"
38533
- (onClick)="handleAction(action, $index)"
38534
- />
38535
- }
38536
- <ng-content select="[modal-actions]" />
38537
- </div>
38538
- </ion-footer>
38539
- }
38540
- `, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;min-height:0}.val-modal-layout__footer{flex-shrink:0;background:var( --ion-card-background, var(--ion-background-color, #fff) );border-top:1px solid var(--ion-border-color, #e7e4ea)}.val-modal-layout__actions{display:flex;align-items:center;gap:var(--val-modal-footer-gap, 8px);padding:var(--val-modal-footer-padding, 12px 16px);padding-bottom:calc(var(--val-modal-footer-padding-bottom, 12px) + var(--ion-safe-area-bottom, env(safe-area-inset-bottom, 0px)))}.val-modal-layout__actions--start{justify-content:flex-start}.val-modal-layout__actions--center{justify-content:center}.val-modal-layout__actions--end{justify-content:flex-end}.val-modal-layout__actions--space-between{justify-content:space-between}.val-modal-layout__actions--auto,.val-modal-layout__actions--stretch{justify-content:flex-end}.val-modal-layout__actions--auto .val-modal-layout__button,.val-modal-layout__actions--stretch .val-modal-layout__button{flex:1 1 auto;min-width:0;display:block}.val-modal-layout__actions--auto .val-modal-layout__button ::ng-deep ion-button,.val-modal-layout__actions--stretch .val-modal-layout__button ::ng-deep ion-button{width:100%}@media (min-width: 481px){.val-modal-layout__actions--auto .val-modal-layout__button,.val-modal-layout__actions--stretch .val-modal-layout__button{flex:0 0 auto;display:inline-block}.val-modal-layout__actions--auto .val-modal-layout__button ::ng-deep ion-button,.val-modal-layout__actions--stretch .val-modal-layout__button ::ng-deep ion-button{width:auto}}@media (max-width: 480px){.val-modal-layout__actions{padding-left:var(--val-modal-footer-padding-inline-mobile, 16px);padding-right:var(--val-modal-footer-padding-inline-mobile, 16px)}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: ModalShellComponent, selector: "val-modal-shell", inputs: ["title", "subtitle", "closeLabel", "showClose"], outputs: ["close"] }] }); }
38541
- }
38542
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalLayoutComponent, decorators: [{
38543
- type: Component,
38544
- args: [{ selector: 'val-modal-layout', standalone: true, imports: [NgClass, IonFooter, ButtonComponent, ModalShellComponent], template: `
38545
- <val-modal-shell
38546
- [title]="title()"
38547
- [subtitle]="subtitle()"
38548
- [closeLabel]="closeLabel()"
38549
- [showClose]="showClose()"
38550
- (close)="close.emit()"
38551
- >
38552
- <ng-content />
38553
- </val-modal-shell>
38554
-
38555
- @if (showFooter()) {
38556
- <ion-footer class="val-modal-layout__footer" [ngClass]="footerClass()">
38557
- <div
38558
- class="val-modal-layout__actions"
38559
- [ngClass]="'val-modal-layout__actions--' + actionsAlign()"
38560
- >
38561
- @for (action of actions(); track action.token || action.text || $index) {
38562
- <val-button
38563
- class="val-modal-layout__button"
38564
- [props]="action"
38565
- (onClick)="handleAction(action, $index)"
38566
- />
38567
- }
38568
- <ng-content select="[modal-actions]" />
38569
- </div>
38570
- </ion-footer>
38571
- }
38572
- `, styles: [":host{display:flex;flex-direction:column;height:100%;min-height:0}.val-modal-layout__footer{flex-shrink:0;background:var( --ion-card-background, var(--ion-background-color, #fff) );border-top:1px solid var(--ion-border-color, #e7e4ea)}.val-modal-layout__actions{display:flex;align-items:center;gap:var(--val-modal-footer-gap, 8px);padding:var(--val-modal-footer-padding, 12px 16px);padding-bottom:calc(var(--val-modal-footer-padding-bottom, 12px) + var(--ion-safe-area-bottom, env(safe-area-inset-bottom, 0px)))}.val-modal-layout__actions--start{justify-content:flex-start}.val-modal-layout__actions--center{justify-content:center}.val-modal-layout__actions--end{justify-content:flex-end}.val-modal-layout__actions--space-between{justify-content:space-between}.val-modal-layout__actions--auto,.val-modal-layout__actions--stretch{justify-content:flex-end}.val-modal-layout__actions--auto .val-modal-layout__button,.val-modal-layout__actions--stretch .val-modal-layout__button{flex:1 1 auto;min-width:0;display:block}.val-modal-layout__actions--auto .val-modal-layout__button ::ng-deep ion-button,.val-modal-layout__actions--stretch .val-modal-layout__button ::ng-deep ion-button{width:100%}@media (min-width: 481px){.val-modal-layout__actions--auto .val-modal-layout__button,.val-modal-layout__actions--stretch .val-modal-layout__button{flex:0 0 auto;display:inline-block}.val-modal-layout__actions--auto .val-modal-layout__button ::ng-deep ion-button,.val-modal-layout__actions--stretch .val-modal-layout__button ::ng-deep ion-button{width:auto}}@media (max-width: 480px){.val-modal-layout__actions{padding-left:var(--val-modal-footer-padding-inline-mobile, 16px);padding-right:var(--val-modal-footer-padding-inline-mobile, 16px)}}\n"] }]
38573
- }] });
38574
-
38575
38596
  /**
38576
38597
  * Configuración de espaciado predefinida
38577
38598
  */
@@ -89631,5 +89652,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
89631
89652
  * Generated bundle index. Do not edit.
89632
89653
  */
89633
89654
 
89634
- export { ACCESS_REQUEST_TYPE, ACCESS_REQUEST_VIEW_I18N, ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, APP_VERSION_PLATFORM_PLUGIN, APP_VERSION_REMOTE_PLUGIN, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AboutViewComponent, AccessControlService, AccessRequestViewComponent, AccordionComponent, AccountViewComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimalCardComponent, AnimatedTerminalComponent, ApiKeyCreateModalComponent, ApiKeyService, ApiKeysModalComponent, ApiKeysViewComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BackButtonComponent, BannerComponent, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, BubbleBlitzGameComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CanAccessDirective, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, ChatComposerComponent, ChatInputComponent, ChatWindowComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ChipSelectComponent, ClientTelemetryService, CodeDisplayComponent, CodeValidatorComponent, CollectionsService, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ConfirmationDialogV2Component, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentReactionModalComponent, ContentService, ContentTransformer, ConversationListItemComponent, ConversationService, CookieBannerComponent, CookieSettingsComponent, 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_CANONICAL_FIELD_ALIASES, 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_LOGIN_LOGO, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_POST_UPDATE_GRACE_MS, DEFAULT_PRESETS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DangerSectionComponent, DataTableComponent, DatasetPaginationService, 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, EXPECTED_NOT_FOUND, EditOrgModalComponent, EmptyStateComponent, EntityCardComponent, EntityFeedService, EntradaSerializada, ExpandableTextComponent, ExternalBrowserService, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeatureControlService, FeatureGuardDirective, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FieldListComponent, FieldOptionsEditorComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FolderTabsComponent, FontSizeOption, FontSizeSelectorComponent, FontSizeService, FooterComponent, FooterLinksComponent, FormComponent, FormFieldComponent, FormSchemaBuilderService, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GAME_AVATAR_CATALOG_SIZE_PER_STYLE, GameAvatarComponent, GameProfileService, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, GroupMembersComponent, GroupPickerComponent, GroupsService, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandleService, HandoffService, HapticsService, HasPermissionDirective, HeaderActionsService, HeaderComponent, HintComponent, HorizontalScrollComponent, HrefComponent, HtmlViewerModalComponent, 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, KNOWN_ROUTES, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGGED_IN_HINT_COOKIE, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LanguageSelectorV2Component, LayeredCardComponent, LegalContentService, LegalLinkService, LightRippleDirective, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LiveReadFallbackService, LoadMoreComponent, LoadingDirective, LocalStorageService, LocaleService, LoginAttemptModalComponent, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, METADATA_LIST_DEFAULTS, META_SCHEMA_VERSION, METRIC_CARD_DEFAULTS, MINI_GAMES_I18N, MINI_GAME_PLAYER_AVATARS, MINI_GAME_PLAYER_COLORS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MediaViewerModalComponent, MemberCardComponent, MemberDetailModalComponent, MemberImportModalComponent, MemoryGameComponent, MenuComponent, MessageBubbleComponent, MessagingService, MetaService, MetadataListComponent, MeteringService, MetricCardComponent, MfaModalComponent, MiniGameCalloutComponent, MiniGamePlayerProfileService, MiniGameScorePopComponent, MiniGamesMenuComponent, ModalLayoutComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NoticeComponent, NotificationActionService, NotificationPreferencesViewComponent, NotificationsService, NotificationsViewComponent, NumberFromToComponent, NumberPickerComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OperationReferenceComponent, OptionCardsComponent, OptionSheetComponent, OptionSheetService, OrgInfoSheetComponent, OrgService, OrgSwitchService, OrganizationViewComponent, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PERSONA_CONFIG, PLATFORM_CONFIGS, POST_UPDATE_TS_KEY, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PdfService, PermissionCatalogService, PermissionSelectorComponent, PermissionsModalComponent, PermissionsViewComponent, PersonaService, PhoneDisplayComponent, PhoneFormatService, PhoneInputComponent, PickerV2Component, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PreferencesViewComponent, PresetService, PriceTagComponent, PricingTableComponent, ProcessLinksPipe, ProfileCardComponent, ProfileContentComponent, ProfileModalComponent, ProfileSkeletonComponent, ProfileViewComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrBrandValidationError, QrCodeComponent, QrGeneratorService, QrScannerComponent, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, RbacService, ReactionBarComponent, ReactionsService, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestFormComponent, RequestModalComponent, RequestReviewPanelComponent, RequestService, RetroAudioService, RightsFooterComponent, RoleManagerComponent, 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, SectionHeaderComponent, SecurityViewComponent, SegmentControlComponent, SelectSearchComponent, SessionListModalComponent, SessionService, SessionTransitionOverlayComponent, SettingsHubComponent, ShareButtonsComponent, ShareProfileModalComponent, SimonGameComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SplashComponent, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SupportTicketCtaComponent, SwipeCarouselComponent, SwitchOrgModalComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeSelectorComponent, ThemeService, ThreadPanelComponent, TicketCardComponent, TicketCardImageService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TransferOwnershipModalComponent, TranslatePipe, TypedCollection, TypingIndicatorComponent, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UsageMetersComponent, UsageService, UserAvatarComponent, UsernameInputComponent, VALTECH_ACCESS_FEATURES, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_CHAT_CONFIG, VALTECH_COLLECTIONS_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_COPYRIGHT_TEMPLATE, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DIAGRAMS, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_LEGAL_ENTITY, VALTECH_MENU_I18N, VALTECH_NETWORK_ERROR_KEY, VALTECH_REACTIONS_CONFIG, VALTECH_SETTINGS_MENU_LINKS, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VALTECH_WHATSAPP_CONFIG, VAL_REGISTERED_ICONS, VERSION, ValCommentThreadComponent, ValQuotaWarningComponent, ValtechErrorService, VerifyViewComponent, WhatsappFabComponent, WhatsappService, WizardComponent, WizardFooterComponent, WorkflowService, accessGuard, accessGuardFromRoute, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, beautifyLegalArticle, blogPost, buildCompanyFooterProps, buildFooterLinks, buildLegalLinkResolver, buildPath, buildPlatformMenu, buildSettingsCards, buildSideNavItemsFromBottomNav, button, canSubmitRequestType, classifyChip, collections, connectPageRefresh, createErrorStateProps, createFirebaseConfig, createGameAvatarCatalog, createGameAvatarProps, createGlowCardProps, createInitialDatasetState, createInitialPaginationState, createNumberFromToField, createPageState, createPermissionLabeler, createRefreshableStream, createTitleProps, datasetPageFromLegacyCursor, defaultQrBrand, docs, errorLoggingInterceptor, evaluateValtechAccess, extractPathParams, firmaDeSesionDeCustomToken, formatClockTime, formatDateSeparator, formatRelativeTime, gameAvatarCatalogEntryToMetadata, gameAvatarDataUri, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, groupPermissionsByScope, guestGuard, hasEmulators, iconButton, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isIonicColor, isKnownRoute, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, providePersona, provideSplashScreen, provideValtechAboutRoutes, provideValtechAccessFeatures, provideValtechAccountRoutes, provideValtechAds, provideValtechApiKeysRoutes, provideValtechAppConfig, provideValtechAppVersion, provideValtechAppVersionHttp, provideValtechAuth, provideValtechAuthInterceptor, provideValtechChat, provideValtechCollections, provideValtechContent, provideValtechDebugConsole, provideValtechDiagrams, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechNotificationClickActions, provideValtechNotificationPreferencesRoutes, provideValtechNotificationsRoutes, provideValtechOrganizationRoutes, provideValtechPermissionsRoutes, provideValtechPreferencesRoutes, provideValtechPresets, provideValtechProfileRoutes, provideValtechReactions, provideValtechSecurityRoutes, provideValtechSettingsRoutes, provideValtechSite, provideValtechSkeleton, provideValtechWhatsapp, qrContrastRatio, qrErrorCorrectionFor, query, rbacGuard, renderGameAvatarSvg, renderPatternSvgInner, replaceSpecialChars, requestSubmitMode, resolveColor, resolveCopyrightTemplate, resolveInputDefaultValue, resolveIonicColor, resolveWebBaseUrl, roleGuard, roleOf, selectableRequestTypes, storagePaths, suggestEmailFix, superAdminGuard, supportedGameAvatarStyles, toArticle, validateQrBrand, validateRoutes };
89655
+ export { ACCESS_REQUEST_TYPE, ACCESS_REQUEST_VIEW_I18N, ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, APP_VERSION_PLATFORM_PLUGIN, APP_VERSION_REMOTE_PLUGIN, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AboutViewComponent, AccessControlService, AccessRequestViewComponent, AccordionComponent, AccountViewComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimalCardComponent, AnimatedTerminalComponent, ApiKeyCreateModalComponent, ApiKeyService, ApiKeysModalComponent, ApiKeysViewComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BackButtonComponent, BannerComponent, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, BubbleBlitzGameComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CanAccessDirective, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, ChatComposerComponent, ChatInputComponent, ChatWindowComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ChipSelectComponent, ClientTelemetryService, CodeDisplayComponent, CodeValidatorComponent, CollectionsService, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ConfirmationDialogV2Component, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentReactionModalComponent, ContentService, ContentTransformer, ConversationListItemComponent, ConversationService, CookieBannerComponent, CookieSettingsComponent, 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_CANONICAL_FIELD_ALIASES, 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_LOGIN_LOGO, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_POST_UPDATE_GRACE_MS, DEFAULT_PRESETS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DangerSectionComponent, DataTableComponent, DatasetPaginationService, 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, EXPECTED_NOT_FOUND, EditOrgModalComponent, EmptyStateComponent, EntityCardComponent, EntityFeedService, EntradaSerializada, ExpandableTextComponent, ExternalBrowserService, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeatureControlService, FeatureGuardDirective, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FieldListComponent, FieldOptionsEditorComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FolderTabsComponent, FontSizeOption, FontSizeSelectorComponent, FontSizeService, FooterComponent, FooterLinksComponent, FormComponent, FormFieldComponent, FormSchemaBuilderService, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GAME_AVATAR_CATALOG_SIZE_PER_STYLE, GameAvatarComponent, GameProfileService, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, GroupMembersComponent, GroupPickerComponent, GroupsService, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandleService, HandoffService, HapticsService, HasPermissionDirective, HeaderActionsService, HeaderComponent, HintComponent, HorizontalScrollComponent, HrefComponent, HtmlViewerModalComponent, 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, KNOWN_ROUTES, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGGED_IN_HINT_COOKIE, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LanguageSelectorV2Component, LayeredCardComponent, LegalContentService, LegalLinkService, LightRippleDirective, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LiveReadFallbackService, LoadMoreComponent, LoadingDirective, LocalStorageService, LocaleService, LoginAttemptModalComponent, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, METADATA_LIST_DEFAULTS, META_SCHEMA_VERSION, METRIC_CARD_DEFAULTS, MINI_GAMES_I18N, MINI_GAME_PLAYER_AVATARS, MINI_GAME_PLAYER_COLORS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MediaViewerModalComponent, MemberCardComponent, MemberDetailModalComponent, MemberImportModalComponent, MemoryGameComponent, MenuComponent, MessageBubbleComponent, MessagingService, MetaService, MetadataListComponent, MeteringService, MetricCardComponent, MfaModalComponent, MiniGameCalloutComponent, MiniGamePlayerProfileService, MiniGameScorePopComponent, MiniGamesMenuComponent, ModalLayoutComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NoticeComponent, NotificationActionService, NotificationPreferencesViewComponent, NotificationsService, NotificationsViewComponent, NumberFromToComponent, NumberPickerComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OperationReferenceComponent, OptionCardsComponent, OptionSheetComponent, OptionSheetService, OrgInfoSheetComponent, OrgService, OrgSwitchService, OrganizationViewComponent, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PERSONA_CONFIG, PLATFORM_CONFIGS, POST_UPDATE_TS_KEY, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PdfService, PermissionCatalogService, PermissionSelectorComponent, PermissionsModalComponent, PermissionsViewComponent, PersonaService, PhoneDisplayComponent, PhoneFormatService, PhoneInputComponent, PickerV2Component, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PreferencesViewComponent, PresetService, PriceTagComponent, PricingTableComponent, ProcessLinksPipe, ProfileCardComponent, ProfileContentComponent, ProfileModalComponent, ProfileSkeletonComponent, ProfileViewComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrBrandValidationError, QrCodeComponent, QrGeneratorService, QrScannerComponent, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, RbacService, ReactionBarComponent, ReactionsService, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestFormComponent, RequestModalComponent, RequestReviewPanelComponent, RequestService, RetroAudioService, RightsFooterComponent, RoleManagerComponent, 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, SectionHeaderComponent, SecurityViewComponent, SegmentControlComponent, SelectSearchComponent, SelectSearchPickerModalComponent, SessionListModalComponent, SessionService, SessionTransitionOverlayComponent, SettingsHubComponent, ShareButtonsComponent, ShareProfileModalComponent, SimonGameComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SplashComponent, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SupportTicketCtaComponent, SwipeCarouselComponent, SwitchOrgModalComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeSelectorComponent, ThemeService, ThreadPanelComponent, TicketCardComponent, TicketCardImageService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TransferOwnershipModalComponent, TranslatePipe, TypedCollection, TypingIndicatorComponent, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UsageMetersComponent, UsageService, UserAvatarComponent, UsernameInputComponent, VALTECH_ACCESS_FEATURES, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_CHAT_CONFIG, VALTECH_COLLECTIONS_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_COPYRIGHT_TEMPLATE, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DIAGRAMS, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_LEGAL_ENTITY, VALTECH_MENU_I18N, VALTECH_NETWORK_ERROR_KEY, VALTECH_REACTIONS_CONFIG, VALTECH_SETTINGS_MENU_LINKS, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VALTECH_WHATSAPP_CONFIG, VAL_REGISTERED_ICONS, VERSION, ValCommentThreadComponent, ValQuotaWarningComponent, ValtechErrorService, VerifyViewComponent, WhatsappFabComponent, WhatsappService, WizardComponent, WizardFooterComponent, WorkflowService, accessGuard, accessGuardFromRoute, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, beautifyLegalArticle, blogPost, buildCompanyFooterProps, buildFooterLinks, buildLegalLinkResolver, buildPath, buildPlatformMenu, buildSettingsCards, buildSideNavItemsFromBottomNav, button, canSubmitRequestType, classifyChip, collections, connectPageRefresh, createErrorStateProps, createFirebaseConfig, createGameAvatarCatalog, createGameAvatarProps, createGlowCardProps, createInitialDatasetState, createInitialPaginationState, createNumberFromToField, createPageState, createPermissionLabeler, createRefreshableStream, createTitleProps, datasetPageFromLegacyCursor, defaultQrBrand, docs, errorLoggingInterceptor, evaluateValtechAccess, extractPathParams, firmaDeSesionDeCustomToken, formatClockTime, formatDateSeparator, formatRelativeTime, gameAvatarCatalogEntryToMetadata, gameAvatarDataUri, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, groupPermissionsByScope, guestGuard, hasEmulators, iconButton, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isIonicColor, isKnownRoute, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, providePersona, provideSplashScreen, provideValtechAboutRoutes, provideValtechAccessFeatures, provideValtechAccountRoutes, provideValtechAds, provideValtechApiKeysRoutes, provideValtechAppConfig, provideValtechAppVersion, provideValtechAppVersionHttp, provideValtechAuth, provideValtechAuthInterceptor, provideValtechChat, provideValtechCollections, provideValtechContent, provideValtechDebugConsole, provideValtechDiagrams, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechNotificationClickActions, provideValtechNotificationPreferencesRoutes, provideValtechNotificationsRoutes, provideValtechOrganizationRoutes, provideValtechPermissionsRoutes, provideValtechPreferencesRoutes, provideValtechPresets, provideValtechProfileRoutes, provideValtechReactions, provideValtechSecurityRoutes, provideValtechSettingsRoutes, provideValtechSite, provideValtechSkeleton, provideValtechWhatsapp, qrContrastRatio, qrErrorCorrectionFor, query, rbacGuard, renderGameAvatarSvg, renderPatternSvgInner, replaceSpecialChars, requestSubmitMode, resolveColor, resolveCopyrightTemplate, resolveInputDefaultValue, resolveIonicColor, resolveWebBaseUrl, roleGuard, roleOf, selectableRequestTypes, storagePaths, suggestEmailFix, superAdminGuard, supportedGameAvatarStyles, toArticle, validateQrBrand, validateRoutes };
89635
89656
  //# sourceMappingURL=valtech-components.mjs.map