valtech-components 2.0.402 → 2.0.403

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,403 @@ 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
- }
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
7648
  }
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;
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;
7727
7762
  }
7728
7763
  }
7764
+ // Método público para reiniciar el componente
7765
+ reset() {
7766
+ this.selectedItems = [];
7767
+ this.displayValue = '';
7768
+ if (this.props?.control) {
7769
+ this.props.control.setValue('');
7770
+ }
7771
+ this.changeDetector.detectChanges();
7772
+ }
7729
7773
  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>
7774
+ 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: `
7775
+ <ion-input
7776
+ type="text"
7777
+ [value]="displayValue"
7778
+ [placeholder]="props?.placeholder || placeholder"
7779
+ readonly
7780
+ (mousedown)="preventDefaultBehavior($event)"
7781
+ />
7773
7782
 
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>
7783
+ <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
7794
7784
 
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>
7785
+ <ion-modal
7786
+ #modal
7787
+ trigger="open-modal"
7788
+ [initialBreakpoint]="1"
7789
+ [breakpoints]="[0, 0.5, 0.75, 1]"
7790
+ (didDismiss)="cancelModal()"
7791
+ >
7792
+ <ng-template>
7793
+ <ion-header>
7794
+ <ion-toolbar>
7795
+ <ion-title>{{ label }}</ion-title>
7796
+ <ion-buttons slot="end">
7797
+ <ion-button (click)="cancelModal()">Cerrar</ion-button>
7798
+ </ion-buttons>
7799
+ </ion-toolbar>
7800
+ <ion-toolbar>
7801
+ <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
7802
+ </ion-toolbar>
7803
+ </ion-header>
7804
+ <ion-content>
7805
+ <!-- Action buttons for multi-select -->
7806
+ <div class="actions-container" style="padding: 16px; border-bottom: 1px solid var(--ion-color-light-shade);">
7807
+ <ion-button
7808
+ fill="clear"
7809
+ size="small"
7810
+ (click)="selectAll()"
7811
+ [disabled]="filteredItems.length === 0"
7812
+ >
7813
+ Seleccionar todos
7814
+ </ion-button>
7815
+ <ion-button
7816
+ fill="clear"
7817
+ size="small"
7818
+ color="medium"
7819
+ (click)="clearAll()"
7820
+ [disabled]="selectedItems.length === 0"
7821
+ >
7822
+ Limpiar
7823
+ </ion-button>
7824
+ </div>
7807
7825
 
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"] }] }); }
7826
+ <ion-list>
7827
+ <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
7828
+ <ion-checkbox
7829
+ slot="start"
7830
+ [checked]="isItemSelected(item)"
7831
+ ></ion-checkbox>
7832
+ <ion-label>{{ item[labelProperty] }}</ion-label>
7833
+ </ion-item>
7834
+ <ion-item *ngIf="filteredItems.length === 0" lines="none">
7835
+ <ion-label color="dark">No se encontraron resultados</ion-label>
7836
+ </ion-item>
7837
+ </ion-list>
7838
+ </ion-content>
7839
+ </ng-template>
7840
+ </ion-modal>
7841
+ `, 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.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
7842
  }
7819
7843
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectSearchComponent, decorators: [{
7820
7844
  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>
7845
+ args: [{ selector: 'val-multi-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, SearchbarComponent, ReactiveFormsModule], template: `
7846
+ <ion-input
7847
+ type="text"
7848
+ [value]="displayValue"
7849
+ [placeholder]="props?.placeholder || placeholder"
7850
+ readonly
7851
+ (mousedown)="preventDefaultBehavior($event)"
7852
+ />
7864
7853
 
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>
7854
+ <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
7885
7855
 
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>
7856
+ <ion-modal
7857
+ #modal
7858
+ trigger="open-modal"
7859
+ [initialBreakpoint]="1"
7860
+ [breakpoints]="[0, 0.5, 0.75, 1]"
7861
+ (didDismiss)="cancelModal()"
7862
+ >
7863
+ <ng-template>
7864
+ <ion-header>
7865
+ <ion-toolbar>
7866
+ <ion-title>{{ label }}</ion-title>
7867
+ <ion-buttons slot="end">
7868
+ <ion-button (click)="cancelModal()">Cerrar</ion-button>
7869
+ </ion-buttons>
7870
+ </ion-toolbar>
7871
+ <ion-toolbar>
7872
+ <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
7873
+ </ion-toolbar>
7874
+ </ion-header>
7875
+ <ion-content>
7876
+ <!-- Action buttons for multi-select -->
7877
+ <div class="actions-container" style="padding: 16px; border-bottom: 1px solid var(--ion-color-light-shade);">
7878
+ <ion-button
7879
+ fill="clear"
7880
+ size="small"
7881
+ (click)="selectAll()"
7882
+ [disabled]="filteredItems.length === 0"
7883
+ >
7884
+ Seleccionar todos
7885
+ </ion-button>
7886
+ <ion-button
7887
+ fill="clear"
7888
+ size="small"
7889
+ color="medium"
7890
+ (click)="clearAll()"
7891
+ [disabled]="selectedItems.length === 0"
7892
+ >
7893
+ Limpiar
7894
+ </ion-button>
7895
+ </div>
7898
7896
 
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: [{
7897
+ <ion-list>
7898
+ <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
7899
+ <ion-checkbox
7900
+ slot="start"
7901
+ [checked]="isItemSelected(item)"
7902
+ ></ion-checkbox>
7903
+ <ion-label>{{ item[labelProperty] }}</ion-label>
7904
+ </ion-item>
7905
+ <ion-item *ngIf="filteredItems.length === 0" lines="none">
7906
+ <ion-label color="dark">No se encontraron resultados</ion-label>
7907
+ </ion-item>
7908
+ </ion-list>
7909
+ </ion-content>
7910
+ </ng-template>
7911
+ </ion-modal>
7912
+ `, styles: ["ion-header{padding:8px 8px 0}.actions-container{display:flex;justify-content:space-between;align-items:center}\n"] }]
7913
+ }], ctorParameters: () => [], propDecorators: { modal: [{
7913
7914
  type: ViewChild,
7914
- args: ['mainInput']
7915
- }], props: [{
7915
+ args: ['modal']
7916
+ }], label: [{
7916
7917
  type: Input
7917
7918
  }], labelProperty: [{
7918
7919
  type: Input
@@ -7920,6 +7921,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7920
7921
  type: Input
7921
7922
  }], placeholder: [{
7922
7923
  type: Input
7924
+ }], props: [{
7925
+ type: Input
7923
7926
  }] } });
7924
7927
 
7925
7928
  class FormComponent {
@@ -8114,7 +8117,7 @@ class FormComponent {
8114
8117
  ></val-button-group>
8115
8118
  </form>
8116
8119
  </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"] }] }); }
8120
+ `, 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
8121
  }
8119
8122
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormComponent, decorators: [{
8120
8123
  type: Component,