valtech-components 2.0.402 → 2.0.404

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, Component, Input, Output, Injectable, inject, InjectionToken, Inject, ChangeDetectorRef, HostListener, Pipe, ChangeDetectionStrategy, ViewChild, forwardRef } from '@angular/core';
2
+ import { EventEmitter, Component, Input, Output, Injectable, inject, InjectionToken, Inject, ChangeDetectorRef, HostListener, Pipe, ChangeDetectionStrategy, ViewChild } from '@angular/core';
3
3
  import { IonAvatar, IonCard, IonIcon, IonButton, IonSpinner, IonText, IonModal, IonHeader, IonToolbar, IonContent, IonButtons, IonTitle, IonProgressBar, IonCardContent, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCheckbox, IonTextarea, IonDatetime, IonDatetimeButton, IonInput, IonSelect, IonSelectOption, IonLabel, IonRadioGroup, IonRadio, IonSearchbar, IonMenuButton, IonFooter, IonList, IonListHeader, IonNote, IonItem } from '@ionic/angular/standalone';
4
4
  import * as i1 from '@angular/common';
5
5
  import { CommonModule, NgStyle, Location, AsyncPipe, NgFor, NgClass } from '@angular/common';
@@ -10,7 +10,7 @@ import { Router, RouterLink } from '@angular/router';
10
10
  import { Browser } from '@capacitor/browser';
11
11
  import * as i1$1 from '@angular/platform-browser';
12
12
  import * as i1$2 from '@angular/forms';
13
- import { ReactiveFormsModule, FormsModule, Validators, NG_VALUE_ACCESSOR } from '@angular/forms';
13
+ import { ReactiveFormsModule, FormsModule, Validators } from '@angular/forms';
14
14
  import { map as map$1 } from 'rxjs/operators';
15
15
  import * as i1$3 from 'ng-otp-input';
16
16
  import { NgOtpInputComponent, NgOtpInputModule } from 'ng-otp-input';
@@ -7517,402 +7517,421 @@ class MultiSelectSearchComponent {
7517
7517
  constructor() {
7518
7518
  this.labelProperty = 'name';
7519
7519
  this.valueProperty = 'id';
7520
- this.placeholder = '';
7521
7520
  this.langService = inject(LangService);
7521
+ this.icon = inject(IconService);
7522
7522
  this.changeDetector = inject(ChangeDetectorRef);
7523
- // Component state
7524
- this.isOpen = false;
7525
7523
  this.searchTerm = '';
7526
- this.selectedValues = [];
7524
+ this.filteredItems = [];
7525
+ this.selectedItems = [];
7527
7526
  this.displayValue = '';
7528
- this.filteredOptions = [];
7529
- this.searchPlaceholder = '';
7530
- // ControlValueAccessor
7531
- this.onChange = (_value) => { };
7532
- this.onTouched = () => { };
7527
+ this.previousOptions = [];
7528
+ this.isProcessingChanges = false;
7529
+ this.label = this.langService.getText('_global', 'selectOptions', 'Seleccionar opciones');
7533
7530
  this.placeholder = this.langService.getText('_global', 'selectOptions', 'Seleccione opciones');
7534
- this.searchPlaceholder = this.langService.getText('_global', 'search', 'Buscar');
7535
- // Close dropdown when clicking outside
7536
- document.addEventListener('click', this.handleClickOutside.bind(this));
7537
7531
  }
7538
7532
  ngOnInit() {
7539
- console.log('[MultiSelectSearch] ngOnInit:', {
7540
- props: !!this.props,
7541
- options: this.props?.options?.length || 0,
7542
- propsOptions: this.props?.options
7543
- });
7544
7533
  this.applyDefaultValue();
7545
- this.initializeOptions();
7546
- this.syncSelectedValues();
7534
+ this.initializeItems();
7535
+ this.syncControlValueWithSelectedItems();
7547
7536
  this.updateDisplayValue();
7548
- // Force change detection after initialization
7549
- this.changeDetector.detectChanges();
7537
+ this.subscribeToValueChanges();
7550
7538
  }
7551
7539
  ngOnDestroy() {
7552
- document.removeEventListener('click', this.handleClickOutside.bind(this));
7540
+ // Limpiar suscripciones para evitar memory leaks
7541
+ if (this.valueChangesSubscription) {
7542
+ this.valueChangesSubscription.unsubscribe();
7543
+ }
7553
7544
  }
7554
7545
  ngOnChanges(changes) {
7555
- console.log('[MultiSelectSearch] ngOnChanges:', {
7556
- hasPropsChange: !!changes['props'],
7557
- props: !!this.props,
7558
- options: this.props?.options?.length || 0,
7559
- propsOptions: this.props?.options
7560
- });
7561
- if (changes['props'] && this.props) {
7562
- this.initializeOptions();
7563
- this.syncSelectedValues();
7564
- this.updateDisplayValue();
7565
- this.changeDetector.detectChanges();
7546
+ // Evitar bucles infinitos
7547
+ if (this.isProcessingChanges) {
7548
+ return;
7549
+ }
7550
+ // Cuando cambia props o props.options
7551
+ if (changes['props']) {
7552
+ try {
7553
+ this.isProcessingChanges = true;
7554
+ // Desuscribirse del antiguo control si existe
7555
+ if (this.valueChangesSubscription) {
7556
+ this.valueChangesSubscription.unsubscribe();
7557
+ }
7558
+ if (this.props?.options) {
7559
+ // Verificar si las opciones han cambiado realmente
7560
+ const optionsChanged = !this.areOptionsEqual(this.previousOptions, this.props.options);
7561
+ if (optionsChanged) {
7562
+ this.previousOptions = [...this.props.options];
7563
+ this.initializeItems();
7564
+ }
7565
+ }
7566
+ // Sincronizar con el nuevo control si existe
7567
+ this.syncControlValueWithSelectedItems();
7568
+ this.updateDisplayValue();
7569
+ // Suscribirse al nuevo control
7570
+ this.subscribeToValueChanges();
7571
+ }
7572
+ finally {
7573
+ this.isProcessingChanges = false;
7574
+ }
7566
7575
  }
7567
7576
  }
7568
- // ControlValueAccessor implementation
7569
- writeValue(value) {
7570
- const valueArray = this.parseValue(value);
7571
- this.selectedValues = valueArray;
7572
- this.updateDisplayValue();
7573
- }
7574
- registerOnChange(fn) {
7575
- this.onChange = fn;
7576
- }
7577
- registerOnTouched(fn) {
7578
- this.onTouched = fn;
7577
+ ionViewWillEnter() {
7578
+ if (this.isProcessingChanges) {
7579
+ return;
7580
+ }
7581
+ try {
7582
+ this.isProcessingChanges = true;
7583
+ this.initializeItems();
7584
+ this.syncControlValueWithSelectedItems();
7585
+ this.updateDisplayValue();
7586
+ this.subscribeToValueChanges();
7587
+ }
7588
+ finally {
7589
+ this.isProcessingChanges = false;
7590
+ }
7579
7591
  }
7580
- setDisabledState(_isDisabled) {
7581
- // Handle disabled state if needed
7592
+ // Suscribirse a cambios en el FormControl
7593
+ subscribeToValueChanges() {
7594
+ if (!this.props?.control)
7595
+ return;
7596
+ this.valueChangesSubscription = this.props.control.valueChanges.subscribe(value => {
7597
+ if (this.isProcessingChanges)
7598
+ return;
7599
+ try {
7600
+ this.isProcessingChanges = true;
7601
+ this.syncControlValueWithSelectedItems();
7602
+ this.updateDisplayValue();
7603
+ }
7604
+ finally {
7605
+ this.isProcessingChanges = false;
7606
+ }
7607
+ });
7582
7608
  }
7583
- // Component methods
7584
- toggleDropdown(event) {
7585
- event.stopPropagation();
7586
- this.isOpen = !this.isOpen;
7587
- if (this.isOpen) {
7588
- this.onTouched();
7589
- // Focus search bar when opening
7590
- setTimeout(() => {
7591
- const searchbar = this.dropdownRef?.nativeElement?.querySelector('ion-searchbar');
7592
- if (searchbar) {
7593
- searchbar.setFocus();
7594
- }
7595
- }, 100);
7609
+ // Compara si dos arrays de opciones son iguales
7610
+ areOptionsEqual(prevOptions, newOptions) {
7611
+ if (prevOptions === newOptions)
7612
+ return true;
7613
+ if (!prevOptions || !newOptions)
7614
+ return prevOptions === newOptions;
7615
+ if (prevOptions.length !== newOptions.length)
7616
+ return false;
7617
+ for (let i = 0; i < prevOptions.length; i++) {
7618
+ if (prevOptions[i][this.valueProperty] !== newOptions[i][this.valueProperty]) {
7619
+ return false;
7620
+ }
7596
7621
  }
7622
+ return true;
7597
7623
  }
7598
- onSearch(event) {
7599
- this.searchTerm = event.detail.value || '';
7600
- this.filterOptions();
7624
+ initializeItems() {
7625
+ this.filteredItems = this.props?.options || [];
7601
7626
  }
7602
- toggleOption(option) {
7603
- const value = String(option[this.valueProperty]);
7604
- if (this.isSelected(option)) {
7605
- // Remove from selection
7606
- this.selectedValues = this.selectedValues.filter(v => v !== value);
7627
+ syncControlValueWithSelectedItems() {
7628
+ if (!this.props?.control) {
7629
+ this.selectedItems = [];
7630
+ return;
7631
+ }
7632
+ const controlValue = this.props.control.value;
7633
+ if (controlValue === null || controlValue === undefined || controlValue === '') {
7634
+ this.selectedItems = [];
7635
+ return;
7636
+ }
7637
+ // Parse comma-separated values for multi-select
7638
+ const values = typeof controlValue === 'string'
7639
+ ? controlValue.split(',').map(v => v.trim()).filter(v => v !== '')
7640
+ : Array.isArray(controlValue) ? controlValue : [controlValue];
7641
+ if (this.props.options && this.props.options.length > 0) {
7642
+ const map = new Map(this.props.options.map(opt => [String(opt[this.valueProperty]), opt]));
7643
+ this.selectedItems = values.map(val => map.get(String(val))).filter(Boolean);
7607
7644
  }
7608
7645
  else {
7609
- // Add to selection
7610
- this.selectedValues = [...this.selectedValues, value];
7646
+ this.selectedItems = [];
7611
7647
  }
7612
- this.updateDisplayValue();
7613
- this.emitValue();
7614
7648
  }
7615
- selectAll() {
7616
- const allValues = this.filteredOptions.map(option => String(option[this.valueProperty]));
7617
- // Add only new values to avoid duplicates
7618
- const newValues = allValues.filter(value => !this.selectedValues.includes(value));
7619
- this.selectedValues = [...this.selectedValues, ...newValues];
7620
- this.updateDisplayValue();
7621
- this.emitValue();
7622
- }
7623
- clearAll() {
7624
- this.selectedValues = [];
7625
- this.updateDisplayValue();
7626
- this.emitValue();
7627
- }
7628
- isSelected(option) {
7629
- return this.selectedValues.includes(String(option[this.valueProperty]));
7630
- }
7631
- trackByFn(_index, option) {
7632
- return option[this.valueProperty];
7633
- }
7634
- debugOptions() {
7635
- console.log('[MultiSelectSearch] DEBUG CLICK:', {
7636
- props: this.props,
7637
- filteredOptions: this.filteredOptions,
7638
- searchTerm: this.searchTerm,
7639
- propsOptions: this.props?.options,
7640
- displayValue: this.displayValue,
7641
- selectedValues: this.selectedValues,
7642
- isOpen: this.isOpen
7643
- });
7649
+ applyDefaultValue() {
7650
+ applyDefaultValueToControl(this.props);
7644
7651
  }
7645
- handleClickOutside(event) {
7646
- if (this.isOpen &&
7647
- !this.mainInputRef?.nativeElement?.contains(event.target) &&
7648
- !this.dropdownRef?.nativeElement?.contains(event.target)) {
7649
- this.isOpen = false;
7650
- this.searchTerm = '';
7651
- this.initializeOptions();
7652
+ onFilter(event) {
7653
+ // If no search term, show all options
7654
+ if (!event || event.trim() === '') {
7655
+ this.filteredItems = this.props?.options ? [...this.props.options] : [];
7656
+ this.changeDetector.detectChanges();
7657
+ return;
7652
7658
  }
7653
- }
7654
- parseValue(value) {
7655
- if (!value)
7656
- return [];
7657
- if (Array.isArray(value))
7658
- return value.map(v => String(v));
7659
- if (typeof value === 'string') {
7660
- return value
7661
- .split(',')
7662
- .map(v => v.trim())
7663
- .filter(v => v !== '');
7664
- }
7665
- return [String(value)];
7666
- }
7667
- emitValue() {
7668
- const value = this.selectedValues.join(',');
7669
- this.onChange(value);
7670
- if (this.props?.control) {
7671
- this.props.control.setValue(value);
7672
- this.props.control.markAsDirty();
7673
- this.props.control.markAsTouched();
7659
+ // If no options, nothing to filter
7660
+ if (!this.props?.options || this.props.options.length === 0) {
7661
+ this.filteredItems = [];
7662
+ this.changeDetector.detectChanges();
7663
+ return;
7674
7664
  }
7665
+ const search = replaceSpecialChars(event.toLowerCase());
7666
+ this.filteredItems = this.props.options.filter(element => {
7667
+ const label = element[this.labelProperty]
7668
+ ? replaceSpecialChars(String(element[this.labelProperty]).toLowerCase())
7669
+ : '';
7670
+ const value = element[this.valueProperty]
7671
+ ? replaceSpecialChars(String(element[this.valueProperty]).toLowerCase())
7672
+ : '';
7673
+ return label.includes(search) || value.includes(search);
7674
+ });
7675
+ this.changeDetector.detectChanges();
7675
7676
  }
7676
- getOptionByValue(value) {
7677
- return this.filteredOptions.find(option => String(option[this.valueProperty]) === String(value));
7677
+ onFocus() {
7678
+ console.log('onFocus');
7678
7679
  }
7679
- applyDefaultValue() {
7680
- if (this.props) {
7681
- applyDefaultValueToControl(this.props);
7680
+ onBlur() {
7681
+ console.log('onBlur');
7682
+ }
7683
+ openModal() {
7684
+ if (this.modal) {
7685
+ this.modal.present();
7682
7686
  }
7683
7687
  }
7684
- initializeOptions() {
7685
- console.log('[MultiSelectSearch] initializeOptions:', {
7686
- propsOptions: this.props?.options,
7687
- optionsLength: this.props?.options?.length || 0
7688
- });
7689
- this.filteredOptions = this.props?.options || [];
7690
- console.log('[MultiSelectSearch] filteredOptions set to:', this.filteredOptions);
7691
- // Force change detection
7688
+ preventDefaultBehavior(event) {
7689
+ event.preventDefault();
7690
+ event.stopPropagation();
7691
+ this.openModal();
7692
+ }
7693
+ cancelModal() {
7694
+ // Reset filter and show all options when closing modal
7695
+ this.searchTerm = '';
7696
+ this.filteredItems = this.props?.options ? [...this.props.options] : [];
7692
7697
  this.changeDetector.detectChanges();
7698
+ if (this.modal) {
7699
+ this.modal.dismiss();
7700
+ }
7693
7701
  }
7694
- filterOptions() {
7695
- if (!this.searchTerm) {
7696
- this.initializeOptions();
7697
- return;
7702
+ selectItem(item) {
7703
+ // Multi-select logic: toggle selection
7704
+ const index = this.selectedItems.findIndex(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
7705
+ if (index === -1) {
7706
+ // Add to selection
7707
+ this.selectedItems.push(item);
7698
7708
  }
7699
- const search = replaceSpecialChars(this.searchTerm.toLowerCase());
7700
- this.filteredOptions = (this.props?.options || []).filter(option => {
7701
- const label = option[this.labelProperty]
7702
- ? replaceSpecialChars(String(option[this.labelProperty]).toLowerCase())
7703
- : '';
7704
- const value = option[this.valueProperty]
7705
- ? replaceSpecialChars(String(option[this.valueProperty]).toLowerCase())
7706
- : '';
7707
- return label.includes(search) || value.includes(search);
7709
+ else {
7710
+ // Remove from selection
7711
+ this.selectedItems.splice(index, 1);
7712
+ }
7713
+ this.updateDisplayValue();
7714
+ this.applyChanges();
7715
+ }
7716
+ selectAll() {
7717
+ // Add all filtered items that aren't already selected
7718
+ this.filteredItems.forEach(item => {
7719
+ const isAlreadySelected = this.selectedItems.some(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
7720
+ if (!isAlreadySelected) {
7721
+ this.selectedItems.push(item);
7722
+ }
7708
7723
  });
7724
+ this.updateDisplayValue();
7725
+ this.applyChanges();
7726
+ }
7727
+ clearAll() {
7728
+ this.selectedItems = [];
7729
+ this.updateDisplayValue();
7730
+ this.applyChanges();
7731
+ }
7732
+ isItemSelected(item) {
7733
+ return this.selectedItems.some(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
7709
7734
  }
7710
7735
  updateDisplayValue() {
7711
- if (this.selectedValues.length === 0) {
7736
+ if (this.selectedItems.length === 0) {
7712
7737
  this.displayValue = '';
7713
7738
  return;
7714
7739
  }
7715
- if (this.selectedValues.length === 1) {
7716
- const option = this.getOptionByValue(this.selectedValues[0]);
7717
- this.displayValue = option ? option[this.labelProperty] : '';
7740
+ if (this.selectedItems.length === 1) {
7741
+ this.displayValue = this.selectedItems[0][this.labelProperty];
7718
7742
  }
7719
7743
  else {
7720
- this.displayValue = `${this.selectedValues.length} elementos seleccionados`;
7744
+ this.displayValue = `${this.selectedItems.length} elementos seleccionados`;
7721
7745
  }
7722
7746
  }
7723
- syncSelectedValues() {
7724
- if (this.props?.control?.value) {
7725
- const valueArray = this.parseValue(this.props.control.value);
7726
- this.selectedValues = valueArray;
7747
+ applyChanges() {
7748
+ if (!this.props?.control) {
7749
+ return;
7727
7750
  }
7751
+ try {
7752
+ this.isProcessingChanges = true;
7753
+ // Convert selected items to comma-separated string of values
7754
+ const selectedValues = this.selectedItems.map(item => String(item[this.valueProperty]));
7755
+ const value = selectedValues.join(',');
7756
+ this.props.control.setValue(value);
7757
+ this.props.control.markAsDirty();
7758
+ this.props.control.updateValueAndValidity();
7759
+ }
7760
+ finally {
7761
+ this.isProcessingChanges = false;
7762
+ }
7763
+ }
7764
+ applyAndClose() {
7765
+ this.applyChanges();
7766
+ this.cancelModal();
7767
+ }
7768
+ // Método público para reiniciar el componente
7769
+ reset() {
7770
+ this.selectedItems = [];
7771
+ this.displayValue = '';
7772
+ if (this.props?.control) {
7773
+ this.props.control.setValue('');
7774
+ }
7775
+ this.changeDetector.detectChanges();
7728
7776
  }
7729
7777
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7730
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MultiSelectSearchComponent, isStandalone: true, selector: "val-multi-select-search", inputs: { props: "props", labelProperty: "labelProperty", valueProperty: "valueProperty", placeholder: "placeholder" }, providers: [
7731
- {
7732
- provide: NG_VALUE_ACCESSOR,
7733
- useExisting: forwardRef(() => MultiSelectSearchComponent),
7734
- multi: true,
7735
- },
7736
- ], viewQueries: [{ propertyName: "dropdownRef", first: true, predicate: ["dropdown"], descendants: true }, { propertyName: "mainInputRef", first: true, predicate: ["mainInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
7737
- <div class="multi-select-container" (click)="toggleDropdown($event)">
7738
- <!-- Main input display -->
7739
- <ion-input
7740
- #mainInput
7741
- type="text"
7742
- [value]="displayValue"
7743
- [placeholder]="props?.placeholder || placeholder"
7744
- readonly
7745
- class="main-input"
7746
- [class.is-open]="isOpen"
7747
- />
7748
-
7749
- <!-- Dropdown icon -->
7750
- <ion-icon name="chevron-down-outline" class="dropdown-icon" [class.rotated]="isOpen"></ion-icon>
7751
-
7752
- <!-- Hidden input for form control -->
7753
- <ion-input
7754
- style="position: absolute; opacity: 0; pointer-events: none;"
7755
- [formControl]="props?.control"
7756
- type="hidden"
7757
- />
7758
- </div>
7759
-
7760
- <!-- Dropdown overlay -->
7761
- <div class="dropdown-overlay" [class.visible]="isOpen" #dropdown>
7762
- <!-- Search bar -->
7763
- <div class="search-container" *ngIf="props?.options && props.options.length > 5">
7764
- <ion-searchbar
7765
- #searchbar
7766
- [placeholder]="searchPlaceholder"
7767
- (ionInput)="onSearch($event)"
7768
- [value]="searchTerm"
7769
- show-clear-button="focus"
7770
- [debounce]="200"
7771
- ></ion-searchbar>
7772
- </div>
7778
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MultiSelectSearchComponent, isStandalone: true, selector: "val-multi-select-search", inputs: { label: "label", labelProperty: "labelProperty", valueProperty: "valueProperty", placeholder: "placeholder", props: "props" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
7779
+ <ion-input
7780
+ type="text"
7781
+ [value]="displayValue"
7782
+ [placeholder]="props?.placeholder || placeholder"
7783
+ readonly
7784
+ (mousedown)="preventDefaultBehavior($event)"
7785
+ />
7773
7786
 
7774
- <!-- Debug button -->
7775
- <div class="search-container" style="background: red; color: white; padding: 4px;">
7776
- <button (click)="debugOptions()">DEBUG: {{ filteredOptions.length }} opciones</button>
7777
- </div>
7778
-
7779
- <!-- Action buttons -->
7780
- <div class="actions-container">
7781
- <ion-button fill="clear" size="small" (click)="selectAll()" [disabled]="filteredOptions.length === 0">
7782
- Seleccionar todos
7783
- </ion-button>
7784
- <ion-button
7785
- fill="clear"
7786
- size="small"
7787
- color="medium"
7788
- (click)="clearAll()"
7789
- [disabled]="selectedValues.length === 0"
7790
- >
7791
- Limpiar
7792
- </ion-button>
7793
- </div>
7787
+ <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
7794
7788
 
7795
- <!-- Options list -->
7796
- <div class="options-container">
7797
- <ion-list class="options-list">
7798
- <ion-item
7799
- *ngFor="let option of filteredOptions; trackBy: trackByFn"
7800
- button
7801
- (click)="toggleOption(option)"
7802
- class="option-item"
7803
- >
7804
- <ion-checkbox slot="start" [checked]="isSelected(option)"></ion-checkbox>
7805
- <ion-label>{{ option[labelProperty] }}</ion-label>
7806
- </ion-item>
7789
+ <ion-modal
7790
+ #modal
7791
+ trigger="open-modal"
7792
+ [initialBreakpoint]="1"
7793
+ [breakpoints]="[0, 0.5, 0.75, 1]"
7794
+ (didDismiss)="cancelModal()"
7795
+ >
7796
+ <ng-template>
7797
+ <ion-header>
7798
+ <ion-toolbar>
7799
+ <ion-title>{{ label }}</ion-title>
7800
+ <ion-buttons slot="end">
7801
+ <ion-button (click)="cancelModal()">Cerrar</ion-button>
7802
+ </ion-buttons>
7803
+ </ion-toolbar>
7804
+ <ion-toolbar>
7805
+ <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
7806
+ </ion-toolbar>
7807
+ </ion-header>
7808
+ <ion-content>
7809
+ <!-- Action buttons for multi-select -->
7810
+ <div class="actions-container" style="padding: 16px; border-bottom: 1px solid var(--ion-color-light-shade);">
7811
+ <ion-button
7812
+ fill="clear"
7813
+ size="small"
7814
+ (click)="selectAll()"
7815
+ [disabled]="filteredItems.length === 0"
7816
+ >
7817
+ Seleccionar todos
7818
+ </ion-button>
7819
+ <ion-button
7820
+ fill="clear"
7821
+ size="small"
7822
+ color="medium"
7823
+ (click)="clearAll()"
7824
+ [disabled]="selectedItems.length === 0"
7825
+ >
7826
+ Limpiar
7827
+ </ion-button>
7828
+ </div>
7807
7829
 
7808
- <!-- No results message -->
7809
- <ion-item *ngIf="filteredOptions.length === 0" class="no-results">
7810
- <ion-label color="medium">
7811
- {{ searchTerm ? 'No se encontraron resultados' : 'No hay opciones disponibles' }}
7812
- </ion-label>
7813
- </ion-item>
7814
- </ion-list>
7815
- </div>
7816
- </div>
7817
- `, isInline: true, styles: [".multi-select-container{position:relative;display:flex;align-items:center;width:100%}.multi-select-container .main-input{flex:1;cursor:pointer}.multi-select-container .main-input.is-open{border-color:var(--ion-color-primary)}.multi-select-container .dropdown-icon{position:absolute;right:12px;font-size:16px;color:var(--ion-color-medium);transition:transform .2s ease;pointer-events:none}.multi-select-container .dropdown-icon.rotated{transform:rotate(180deg)}.dropdown-overlay{position:absolute;top:100%;left:0;right:0;z-index:1000;background:var(--ion-color-light);border:1px solid var(--ion-color-medium);border-radius:8px;box-shadow:0 4px 16px #00000026;max-height:300px;overflow:hidden;opacity:0;visibility:hidden;transform:translateY(-10px);transition:all .2s ease}.dropdown-overlay.visible{opacity:1;visibility:visible;transform:translateY(0)}.dropdown-overlay .search-container{padding:8px;border-bottom:1px solid var(--ion-color-light-shade)}.dropdown-overlay .search-container ion-searchbar{--background: var(--ion-color-light);--border-radius: 6px;--box-shadow: none;padding:0}.dropdown-overlay .actions-container{display:flex;justify-content:space-between;padding:8px;border-bottom:1px solid var(--ion-color-light-shade);background:var(--ion-color-light-tint)}.dropdown-overlay .actions-container ion-button{--padding-start: 8px;--padding-end: 8px;font-size:12px;height:28px}.dropdown-overlay .options-container{max-height:200px;overflow-y:auto}.dropdown-overlay .options-container .options-list{padding:0;margin:0}.dropdown-overlay .options-container .options-list .option-item{--padding-start: 12px;--padding-end: 12px;--inner-padding-end: 0;cursor:pointer;transition:background-color .2s ease}.dropdown-overlay .options-container .options-list .option-item:hover{--background: var(--ion-color-light-shade)}.dropdown-overlay .options-container .options-list .option-item ion-checkbox{margin-right:12px}.dropdown-overlay .options-container .options-list .option-item ion-label{font-size:14px;color:var(--ion-color-dark)}.dropdown-overlay .options-container .options-list .no-results{--padding-start: 12px;--padding-end: 12px;cursor:default}.dropdown-overlay .options-container .options-list .no-results ion-label{font-size:14px;font-style:italic}@media (prefers-color-scheme: dark){.dropdown-overlay{background:var(--ion-color-dark);border-color:var(--ion-color-medium-shade)}.dropdown-overlay .search-container{border-bottom-color:var(--ion-color-dark-shade)}.dropdown-overlay .search-container ion-searchbar{--background: var(--ion-color-dark-tint)}.dropdown-overlay .actions-container{border-bottom-color:var(--ion-color-dark-shade);background:var(--ion-color-dark-tint)}.dropdown-overlay .options-list .option-item:hover{--background: var(--ion-color-dark-shade)}.dropdown-overlay .options-list .option-item ion-label{color:var(--ion-color-light)}}@media (max-width: 768px){.dropdown-overlay .options-container{max-height:180px}.dropdown-overlay .actions-container ion-button{font-size:11px;height:26px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "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.IonCheckbox, selector: "ion-checkbox", inputs: ["alignment", "checked", "color", "disabled", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { 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", "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.IonSearchbar, selector: "ion-searchbar", inputs: ["animated", "autocapitalize", "autocomplete", "autocorrect", "cancelButtonIcon", "cancelButtonText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "maxlength", "minlength", "mode", "name", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value"] }, { kind: "directive", type: i2.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
7830
+ <ion-list>
7831
+ <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
7832
+ <ion-checkbox
7833
+ slot="start"
7834
+ [checked]="isItemSelected(item)"
7835
+ ></ion-checkbox>
7836
+ <ion-label>{{ item[labelProperty] }}</ion-label>
7837
+ </ion-item>
7838
+ <ion-item *ngIf="filteredItems.length === 0" lines="none">
7839
+ <ion-label color="dark">No se encontraron resultados</ion-label>
7840
+ </ion-item>
7841
+ </ion-list>
7842
+ </ion-content>
7843
+ <ion-footer>
7844
+ <ion-toolbar>
7845
+ <ion-button expand="full" (click)="applyAndClose()">
7846
+ Aplicar
7847
+ </ion-button>
7848
+ </ion-toolbar>
7849
+ </ion-footer>
7850
+ </ng-template>
7851
+ </ion-modal>
7852
+ `, isInline: true, styles: ["ion-header{padding:8px 8px 0}.actions-container{display:flex;justify-content:space-between;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "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.IonCheckbox, selector: "ion-checkbox", inputs: ["alignment", "checked", "color", "disabled", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["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", "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.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["disabled"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
7818
7853
  }
7819
7854
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectSearchComponent, decorators: [{
7820
7855
  type: Component,
7821
- args: [{ selector: 'val-multi-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, ReactiveFormsModule], providers: [
7822
- {
7823
- provide: NG_VALUE_ACCESSOR,
7824
- useExisting: forwardRef(() => MultiSelectSearchComponent),
7825
- multi: true,
7826
- },
7827
- ], template: `
7828
- <div class="multi-select-container" (click)="toggleDropdown($event)">
7829
- <!-- Main input display -->
7830
- <ion-input
7831
- #mainInput
7832
- type="text"
7833
- [value]="displayValue"
7834
- [placeholder]="props?.placeholder || placeholder"
7835
- readonly
7836
- class="main-input"
7837
- [class.is-open]="isOpen"
7838
- />
7839
-
7840
- <!-- Dropdown icon -->
7841
- <ion-icon name="chevron-down-outline" class="dropdown-icon" [class.rotated]="isOpen"></ion-icon>
7842
-
7843
- <!-- Hidden input for form control -->
7844
- <ion-input
7845
- style="position: absolute; opacity: 0; pointer-events: none;"
7846
- [formControl]="props?.control"
7847
- type="hidden"
7848
- />
7849
- </div>
7850
-
7851
- <!-- Dropdown overlay -->
7852
- <div class="dropdown-overlay" [class.visible]="isOpen" #dropdown>
7853
- <!-- Search bar -->
7854
- <div class="search-container" *ngIf="props?.options && props.options.length > 5">
7855
- <ion-searchbar
7856
- #searchbar
7857
- [placeholder]="searchPlaceholder"
7858
- (ionInput)="onSearch($event)"
7859
- [value]="searchTerm"
7860
- show-clear-button="focus"
7861
- [debounce]="200"
7862
- ></ion-searchbar>
7863
- </div>
7856
+ args: [{ selector: 'val-multi-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, SearchbarComponent, ReactiveFormsModule], template: `
7857
+ <ion-input
7858
+ type="text"
7859
+ [value]="displayValue"
7860
+ [placeholder]="props?.placeholder || placeholder"
7861
+ readonly
7862
+ (mousedown)="preventDefaultBehavior($event)"
7863
+ />
7864
7864
 
7865
- <!-- Debug button -->
7866
- <div class="search-container" style="background: red; color: white; padding: 4px;">
7867
- <button (click)="debugOptions()">DEBUG: {{ filteredOptions.length }} opciones</button>
7868
- </div>
7869
-
7870
- <!-- Action buttons -->
7871
- <div class="actions-container">
7872
- <ion-button fill="clear" size="small" (click)="selectAll()" [disabled]="filteredOptions.length === 0">
7873
- Seleccionar todos
7874
- </ion-button>
7875
- <ion-button
7876
- fill="clear"
7877
- size="small"
7878
- color="medium"
7879
- (click)="clearAll()"
7880
- [disabled]="selectedValues.length === 0"
7881
- >
7882
- Limpiar
7883
- </ion-button>
7884
- </div>
7865
+ <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
7885
7866
 
7886
- <!-- Options list -->
7887
- <div class="options-container">
7888
- <ion-list class="options-list">
7889
- <ion-item
7890
- *ngFor="let option of filteredOptions; trackBy: trackByFn"
7891
- button
7892
- (click)="toggleOption(option)"
7893
- class="option-item"
7894
- >
7895
- <ion-checkbox slot="start" [checked]="isSelected(option)"></ion-checkbox>
7896
- <ion-label>{{ option[labelProperty] }}</ion-label>
7897
- </ion-item>
7867
+ <ion-modal
7868
+ #modal
7869
+ trigger="open-modal"
7870
+ [initialBreakpoint]="1"
7871
+ [breakpoints]="[0, 0.5, 0.75, 1]"
7872
+ (didDismiss)="cancelModal()"
7873
+ >
7874
+ <ng-template>
7875
+ <ion-header>
7876
+ <ion-toolbar>
7877
+ <ion-title>{{ label }}</ion-title>
7878
+ <ion-buttons slot="end">
7879
+ <ion-button (click)="cancelModal()">Cerrar</ion-button>
7880
+ </ion-buttons>
7881
+ </ion-toolbar>
7882
+ <ion-toolbar>
7883
+ <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
7884
+ </ion-toolbar>
7885
+ </ion-header>
7886
+ <ion-content>
7887
+ <!-- Action buttons for multi-select -->
7888
+ <div class="actions-container" style="padding: 16px; border-bottom: 1px solid var(--ion-color-light-shade);">
7889
+ <ion-button
7890
+ fill="clear"
7891
+ size="small"
7892
+ (click)="selectAll()"
7893
+ [disabled]="filteredItems.length === 0"
7894
+ >
7895
+ Seleccionar todos
7896
+ </ion-button>
7897
+ <ion-button
7898
+ fill="clear"
7899
+ size="small"
7900
+ color="medium"
7901
+ (click)="clearAll()"
7902
+ [disabled]="selectedItems.length === 0"
7903
+ >
7904
+ Limpiar
7905
+ </ion-button>
7906
+ </div>
7898
7907
 
7899
- <!-- No results message -->
7900
- <ion-item *ngIf="filteredOptions.length === 0" class="no-results">
7901
- <ion-label color="medium">
7902
- {{ searchTerm ? 'No se encontraron resultados' : 'No hay opciones disponibles' }}
7903
- </ion-label>
7904
- </ion-item>
7905
- </ion-list>
7906
- </div>
7907
- </div>
7908
- `, styles: [".multi-select-container{position:relative;display:flex;align-items:center;width:100%}.multi-select-container .main-input{flex:1;cursor:pointer}.multi-select-container .main-input.is-open{border-color:var(--ion-color-primary)}.multi-select-container .dropdown-icon{position:absolute;right:12px;font-size:16px;color:var(--ion-color-medium);transition:transform .2s ease;pointer-events:none}.multi-select-container .dropdown-icon.rotated{transform:rotate(180deg)}.dropdown-overlay{position:absolute;top:100%;left:0;right:0;z-index:1000;background:var(--ion-color-light);border:1px solid var(--ion-color-medium);border-radius:8px;box-shadow:0 4px 16px #00000026;max-height:300px;overflow:hidden;opacity:0;visibility:hidden;transform:translateY(-10px);transition:all .2s ease}.dropdown-overlay.visible{opacity:1;visibility:visible;transform:translateY(0)}.dropdown-overlay .search-container{padding:8px;border-bottom:1px solid var(--ion-color-light-shade)}.dropdown-overlay .search-container ion-searchbar{--background: var(--ion-color-light);--border-radius: 6px;--box-shadow: none;padding:0}.dropdown-overlay .actions-container{display:flex;justify-content:space-between;padding:8px;border-bottom:1px solid var(--ion-color-light-shade);background:var(--ion-color-light-tint)}.dropdown-overlay .actions-container ion-button{--padding-start: 8px;--padding-end: 8px;font-size:12px;height:28px}.dropdown-overlay .options-container{max-height:200px;overflow-y:auto}.dropdown-overlay .options-container .options-list{padding:0;margin:0}.dropdown-overlay .options-container .options-list .option-item{--padding-start: 12px;--padding-end: 12px;--inner-padding-end: 0;cursor:pointer;transition:background-color .2s ease}.dropdown-overlay .options-container .options-list .option-item:hover{--background: var(--ion-color-light-shade)}.dropdown-overlay .options-container .options-list .option-item ion-checkbox{margin-right:12px}.dropdown-overlay .options-container .options-list .option-item ion-label{font-size:14px;color:var(--ion-color-dark)}.dropdown-overlay .options-container .options-list .no-results{--padding-start: 12px;--padding-end: 12px;cursor:default}.dropdown-overlay .options-container .options-list .no-results ion-label{font-size:14px;font-style:italic}@media (prefers-color-scheme: dark){.dropdown-overlay{background:var(--ion-color-dark);border-color:var(--ion-color-medium-shade)}.dropdown-overlay .search-container{border-bottom-color:var(--ion-color-dark-shade)}.dropdown-overlay .search-container ion-searchbar{--background: var(--ion-color-dark-tint)}.dropdown-overlay .actions-container{border-bottom-color:var(--ion-color-dark-shade);background:var(--ion-color-dark-tint)}.dropdown-overlay .options-list .option-item:hover{--background: var(--ion-color-dark-shade)}.dropdown-overlay .options-list .option-item ion-label{color:var(--ion-color-light)}}@media (max-width: 768px){.dropdown-overlay .options-container{max-height:180px}.dropdown-overlay .actions-container ion-button{font-size:11px;height:26px}}\n"] }]
7909
- }], ctorParameters: () => [], propDecorators: { dropdownRef: [{
7910
- type: ViewChild,
7911
- args: ['dropdown']
7912
- }], mainInputRef: [{
7908
+ <ion-list>
7909
+ <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
7910
+ <ion-checkbox
7911
+ slot="start"
7912
+ [checked]="isItemSelected(item)"
7913
+ ></ion-checkbox>
7914
+ <ion-label>{{ item[labelProperty] }}</ion-label>
7915
+ </ion-item>
7916
+ <ion-item *ngIf="filteredItems.length === 0" lines="none">
7917
+ <ion-label color="dark">No se encontraron resultados</ion-label>
7918
+ </ion-item>
7919
+ </ion-list>
7920
+ </ion-content>
7921
+ <ion-footer>
7922
+ <ion-toolbar>
7923
+ <ion-button expand="full" (click)="applyAndClose()">
7924
+ Aplicar
7925
+ </ion-button>
7926
+ </ion-toolbar>
7927
+ </ion-footer>
7928
+ </ng-template>
7929
+ </ion-modal>
7930
+ `, styles: ["ion-header{padding:8px 8px 0}.actions-container{display:flex;justify-content:space-between;align-items:center}\n"] }]
7931
+ }], ctorParameters: () => [], propDecorators: { modal: [{
7913
7932
  type: ViewChild,
7914
- args: ['mainInput']
7915
- }], props: [{
7933
+ args: ['modal']
7934
+ }], label: [{
7916
7935
  type: Input
7917
7936
  }], labelProperty: [{
7918
7937
  type: Input
@@ -7920,6 +7939,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7920
7939
  type: Input
7921
7940
  }], placeholder: [{
7922
7941
  type: Input
7942
+ }], props: [{
7943
+ type: Input
7923
7944
  }] } });
7924
7945
 
7925
7946
  class FormComponent {
@@ -8114,7 +8135,7 @@ class FormComponent {
8114
8135
  ></val-button-group>
8115
8136
  </form>
8116
8137
  </div>
8117
- `, isInline: true, styles: [":root{--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)}@media (prefers-color-scheme: dark){:root{--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:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextInputComponent, selector: "val-text-input", inputs: ["props"] }, { kind: "component", type: CheckInputComponent, selector: "val-check-input" }, { kind: "component", type: ButtonGroupComponent, selector: "val-button-group", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: DividerComponent, selector: "val-divider", inputs: ["props"] }, { kind: "component", type: HintComponent, selector: "val-hint", inputs: ["props"] }, { kind: "component", type: CommentInputComponent, selector: "val-comment-input", inputs: ["props"] }, { kind: "component", type: DateInputComponent, selector: "val-date-input", inputs: ["props"] }, { kind: "component", type: FileInputComponent, selector: "val-file-input", inputs: ["props"] }, { kind: "component", type: HourInputComponent, selector: "val-hour-input", inputs: ["props"] }, { kind: "component", type: EmailInputComponent, selector: "val-email-input", inputs: ["props"] }, { kind: "component", type: NumberInputComponent, selector: "val-number-input", inputs: ["props"] }, { kind: "component", type: NumberFromToComponent, selector: "val-number-from-to", inputs: ["props"] }, { kind: "component", type: RadioInputComponent, selector: "val-radio-input", inputs: ["props"] }, { kind: "component", type: PasswordInputComponent, selector: "val-password-input", inputs: ["props"] }, { kind: "component", type: PinInputComponent, selector: "val-pin-input", inputs: ["props"] }, { kind: "component", type: SelectSearchComponent, selector: "val-select-search", inputs: ["label", "labelProperty", "valueProperty", "multiple", "placeholder", "props"] }, { kind: "component", type: MultiSelectSearchComponent, selector: "val-multi-select-search", inputs: ["props", "labelProperty", "valueProperty", "placeholder"] }, { kind: "component", type: SearchSelectorComponent, selector: "val-select-input", inputs: ["props"] }] }); }
8138
+ `, isInline: true, styles: [":root{--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)}@media (prefers-color-scheme: dark){:root{--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:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextInputComponent, selector: "val-text-input", inputs: ["props"] }, { kind: "component", type: CheckInputComponent, selector: "val-check-input" }, { kind: "component", type: ButtonGroupComponent, selector: "val-button-group", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: DividerComponent, selector: "val-divider", inputs: ["props"] }, { kind: "component", type: HintComponent, selector: "val-hint", inputs: ["props"] }, { kind: "component", type: CommentInputComponent, selector: "val-comment-input", inputs: ["props"] }, { kind: "component", type: DateInputComponent, selector: "val-date-input", inputs: ["props"] }, { kind: "component", type: FileInputComponent, selector: "val-file-input", inputs: ["props"] }, { kind: "component", type: HourInputComponent, selector: "val-hour-input", inputs: ["props"] }, { kind: "component", type: EmailInputComponent, selector: "val-email-input", inputs: ["props"] }, { kind: "component", type: NumberInputComponent, selector: "val-number-input", inputs: ["props"] }, { kind: "component", type: NumberFromToComponent, selector: "val-number-from-to", inputs: ["props"] }, { kind: "component", type: RadioInputComponent, selector: "val-radio-input", inputs: ["props"] }, { kind: "component", type: PasswordInputComponent, selector: "val-password-input", inputs: ["props"] }, { kind: "component", type: PinInputComponent, selector: "val-pin-input", inputs: ["props"] }, { kind: "component", type: SelectSearchComponent, selector: "val-select-search", inputs: ["label", "labelProperty", "valueProperty", "multiple", "placeholder", "props"] }, { kind: "component", type: MultiSelectSearchComponent, selector: "val-multi-select-search", inputs: ["label", "labelProperty", "valueProperty", "placeholder", "props"] }, { kind: "component", type: SearchSelectorComponent, selector: "val-select-input", inputs: ["props"] }] }); }
8118
8139
  }
8119
8140
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormComponent, decorators: [{
8120
8141
  type: Component,