valtech-components 2.0.401 → 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,398 +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();
7537
+ this.subscribeToValueChanges();
7548
7538
  }
7549
7539
  ngOnDestroy() {
7550
- document.removeEventListener('click', this.handleClickOutside.bind(this));
7540
+ // Limpiar suscripciones para evitar memory leaks
7541
+ if (this.valueChangesSubscription) {
7542
+ this.valueChangesSubscription.unsubscribe();
7543
+ }
7551
7544
  }
7552
7545
  ngOnChanges(changes) {
7553
- console.log('[MultiSelectSearch] ngOnChanges:', {
7554
- hasPropsChange: !!changes['props'],
7555
- props: !!this.props,
7556
- options: this.props?.options?.length || 0,
7557
- propsOptions: this.props?.options
7558
- });
7559
- if (changes['props'] && this.props) {
7560
- this.initializeOptions();
7561
- this.syncSelectedValues();
7562
- this.updateDisplayValue();
7563
- 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
+ }
7564
7575
  }
7565
7576
  }
7566
- // ControlValueAccessor implementation
7567
- writeValue(value) {
7568
- const valueArray = this.parseValue(value);
7569
- this.selectedValues = valueArray;
7570
- this.updateDisplayValue();
7571
- }
7572
- registerOnChange(fn) {
7573
- this.onChange = fn;
7574
- }
7575
- registerOnTouched(fn) {
7576
- 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
+ }
7577
7591
  }
7578
- setDisabledState(_isDisabled) {
7579
- // 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
+ });
7580
7608
  }
7581
- // Component methods
7582
- toggleDropdown(event) {
7583
- event.stopPropagation();
7584
- this.isOpen = !this.isOpen;
7585
- if (this.isOpen) {
7586
- this.onTouched();
7587
- // Focus search bar when opening
7588
- setTimeout(() => {
7589
- const searchbar = this.dropdownRef?.nativeElement?.querySelector('ion-searchbar');
7590
- if (searchbar) {
7591
- searchbar.setFocus();
7592
- }
7593
- }, 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
+ }
7594
7621
  }
7622
+ return true;
7595
7623
  }
7596
- onSearch(event) {
7597
- this.searchTerm = event.detail.value || '';
7598
- this.filterOptions();
7624
+ initializeItems() {
7625
+ this.filteredItems = this.props?.options || [];
7599
7626
  }
7600
- toggleOption(option) {
7601
- const value = String(option[this.valueProperty]);
7602
- if (this.isSelected(option)) {
7603
- // Remove from selection
7604
- 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);
7605
7644
  }
7606
7645
  else {
7607
- // Add to selection
7608
- this.selectedValues = [...this.selectedValues, value];
7646
+ this.selectedItems = [];
7609
7647
  }
7610
- this.updateDisplayValue();
7611
- this.emitValue();
7612
7648
  }
7613
- selectAll() {
7614
- const allValues = this.filteredOptions.map(option => String(option[this.valueProperty]));
7615
- // Add only new values to avoid duplicates
7616
- const newValues = allValues.filter(value => !this.selectedValues.includes(value));
7617
- this.selectedValues = [...this.selectedValues, ...newValues];
7618
- this.updateDisplayValue();
7619
- this.emitValue();
7649
+ applyDefaultValue() {
7650
+ applyDefaultValueToControl(this.props);
7620
7651
  }
7621
- clearAll() {
7622
- this.selectedValues = [];
7623
- this.updateDisplayValue();
7624
- this.emitValue();
7625
- }
7626
- isSelected(option) {
7627
- return this.selectedValues.includes(String(option[this.valueProperty]));
7628
- }
7629
- trackByFn(_index, option) {
7630
- return option[this.valueProperty];
7631
- }
7632
- debugOptions() {
7633
- console.log('[MultiSelectSearch] DEBUG CLICK:', {
7634
- props: this.props,
7635
- filteredOptions: this.filteredOptions,
7636
- searchTerm: this.searchTerm,
7637
- propsOptions: this.props?.options,
7638
- displayValue: this.displayValue,
7639
- selectedValues: this.selectedValues,
7640
- isOpen: this.isOpen
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;
7658
+ }
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;
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);
7641
7674
  });
7675
+ this.changeDetector.detectChanges();
7642
7676
  }
7643
- handleClickOutside(event) {
7644
- if (this.isOpen &&
7645
- !this.mainInputRef?.nativeElement?.contains(event.target) &&
7646
- !this.dropdownRef?.nativeElement?.contains(event.target)) {
7647
- this.isOpen = false;
7648
- this.searchTerm = '';
7649
- this.initializeOptions();
7650
- }
7677
+ onFocus() {
7678
+ console.log('onFocus');
7651
7679
  }
7652
- parseValue(value) {
7653
- if (!value)
7654
- return [];
7655
- if (Array.isArray(value))
7656
- return value.map(v => String(v));
7657
- if (typeof value === 'string') {
7658
- return value
7659
- .split(',')
7660
- .map(v => v.trim())
7661
- .filter(v => v !== '');
7662
- }
7663
- return [String(value)];
7664
- }
7665
- emitValue() {
7666
- const value = this.selectedValues.join(',');
7667
- this.onChange(value);
7668
- if (this.props?.control) {
7669
- this.props.control.setValue(value);
7670
- this.props.control.markAsDirty();
7671
- this.props.control.markAsTouched();
7680
+ onBlur() {
7681
+ console.log('onBlur');
7682
+ }
7683
+ openModal() {
7684
+ if (this.modal) {
7685
+ this.modal.present();
7672
7686
  }
7673
7687
  }
7674
- getOptionByValue(value) {
7675
- return this.filteredOptions.find(option => String(option[this.valueProperty]) === String(value));
7688
+ preventDefaultBehavior(event) {
7689
+ event.preventDefault();
7690
+ event.stopPropagation();
7691
+ this.openModal();
7676
7692
  }
7677
- applyDefaultValue() {
7678
- if (this.props) {
7679
- applyDefaultValueToControl(this.props);
7693
+ cancelModal() {
7694
+ // Reset filter and show all options when closing modal
7695
+ this.searchTerm = '';
7696
+ this.filteredItems = this.props?.options ? [...this.props.options] : [];
7697
+ this.changeDetector.detectChanges();
7698
+ if (this.modal) {
7699
+ this.modal.dismiss();
7680
7700
  }
7681
7701
  }
7682
- initializeOptions() {
7683
- console.log('[MultiSelectSearch] initializeOptions:', {
7684
- propsOptions: this.props?.options,
7685
- optionsLength: this.props?.options?.length || 0
7686
- });
7687
- this.filteredOptions = this.props?.options || [];
7688
- console.log('[MultiSelectSearch] filteredOptions set to:', this.filteredOptions);
7689
- }
7690
- filterOptions() {
7691
- if (!this.searchTerm) {
7692
- this.initializeOptions();
7693
- 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);
7694
7708
  }
7695
- const search = replaceSpecialChars(this.searchTerm.toLowerCase());
7696
- this.filteredOptions = (this.props?.options || []).filter(option => {
7697
- const label = option[this.labelProperty]
7698
- ? replaceSpecialChars(String(option[this.labelProperty]).toLowerCase())
7699
- : '';
7700
- const value = option[this.valueProperty]
7701
- ? replaceSpecialChars(String(option[this.valueProperty]).toLowerCase())
7702
- : '';
7703
- 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
+ }
7704
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]);
7705
7734
  }
7706
7735
  updateDisplayValue() {
7707
- if (this.selectedValues.length === 0) {
7736
+ if (this.selectedItems.length === 0) {
7708
7737
  this.displayValue = '';
7709
7738
  return;
7710
7739
  }
7711
- if (this.selectedValues.length === 1) {
7712
- const option = this.getOptionByValue(this.selectedValues[0]);
7713
- this.displayValue = option ? option[this.labelProperty] : '';
7740
+ if (this.selectedItems.length === 1) {
7741
+ this.displayValue = this.selectedItems[0][this.labelProperty];
7714
7742
  }
7715
7743
  else {
7716
- this.displayValue = `${this.selectedValues.length} elementos seleccionados`;
7744
+ this.displayValue = `${this.selectedItems.length} elementos seleccionados`;
7745
+ }
7746
+ }
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;
7717
7762
  }
7718
7763
  }
7719
- syncSelectedValues() {
7720
- if (this.props?.control?.value) {
7721
- const valueArray = this.parseValue(this.props.control.value);
7722
- this.selectedValues = valueArray;
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('');
7723
7770
  }
7771
+ this.changeDetector.detectChanges();
7724
7772
  }
7725
7773
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7726
- 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: [
7727
- {
7728
- provide: NG_VALUE_ACCESSOR,
7729
- useExisting: forwardRef(() => MultiSelectSearchComponent),
7730
- multi: true,
7731
- },
7732
- ], viewQueries: [{ propertyName: "dropdownRef", first: true, predicate: ["dropdown"], descendants: true }, { propertyName: "mainInputRef", first: true, predicate: ["mainInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
7733
- <div class="multi-select-container" (click)="toggleDropdown($event)">
7734
- <!-- Main input display -->
7735
- <ion-input
7736
- #mainInput
7737
- type="text"
7738
- [value]="displayValue"
7739
- [placeholder]="props?.placeholder || placeholder"
7740
- readonly
7741
- class="main-input"
7742
- [class.is-open]="isOpen"
7743
- />
7744
-
7745
- <!-- Dropdown icon -->
7746
- <ion-icon name="chevron-down-outline" class="dropdown-icon" [class.rotated]="isOpen"></ion-icon>
7747
-
7748
- <!-- Hidden input for form control -->
7749
- <ion-input
7750
- style="position: absolute; opacity: 0; pointer-events: none;"
7751
- [formControl]="props?.control"
7752
- type="hidden"
7753
- />
7754
- </div>
7755
-
7756
- <!-- Dropdown overlay -->
7757
- <div class="dropdown-overlay" [class.visible]="isOpen" #dropdown>
7758
- <!-- Search bar -->
7759
- <div class="search-container" *ngIf="props?.options && props.options.length > 5">
7760
- <ion-searchbar
7761
- #searchbar
7762
- [placeholder]="searchPlaceholder"
7763
- (ionInput)="onSearch($event)"
7764
- [value]="searchTerm"
7765
- show-clear-button="focus"
7766
- [debounce]="200"
7767
- ></ion-searchbar>
7768
- </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
+ />
7769
7782
 
7770
- <!-- Debug button -->
7771
- <div class="search-container" style="background: red; color: white; padding: 4px;">
7772
- <button (click)="debugOptions()">DEBUG: {{ filteredOptions.length }} opciones</button>
7773
- </div>
7774
-
7775
- <!-- Action buttons -->
7776
- <div class="actions-container" *ngIf="filteredOptions.length > 0">
7777
- <ion-button fill="clear" size="small" (click)="selectAll()" [disabled]="filteredOptions.length === 0">
7778
- Seleccionar todos
7779
- </ion-button>
7780
- <ion-button
7781
- fill="clear"
7782
- size="small"
7783
- color="medium"
7784
- (click)="clearAll()"
7785
- [disabled]="selectedValues.length === 0"
7786
- >
7787
- Limpiar
7788
- </ion-button>
7789
- </div>
7783
+ <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
7790
7784
 
7791
- <!-- Options list -->
7792
- <div class="options-container">
7793
- <ion-list class="options-list">
7794
- <ion-item
7795
- *ngFor="let option of filteredOptions; trackBy: trackByFn"
7796
- button
7797
- (click)="toggleOption(option)"
7798
- class="option-item"
7799
- >
7800
- <ion-checkbox slot="start" [checked]="isSelected(option)"></ion-checkbox>
7801
- <ion-label>{{ option[labelProperty] }}</ion-label>
7802
- </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>
7803
7825
 
7804
- <!-- No results message -->
7805
- <ion-item *ngIf="filteredOptions.length === 0" class="no-results">
7806
- <ion-label color="medium">
7807
- {{ searchTerm ? 'No se encontraron resultados' : 'No hay opciones disponibles' }}
7808
- </ion-label>
7809
- </ion-item>
7810
- </ion-list>
7811
- </div>
7812
- </div>
7813
- `, 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"] }] }); }
7814
7842
  }
7815
7843
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectSearchComponent, decorators: [{
7816
7844
  type: Component,
7817
- args: [{ selector: 'val-multi-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, ReactiveFormsModule], providers: [
7818
- {
7819
- provide: NG_VALUE_ACCESSOR,
7820
- useExisting: forwardRef(() => MultiSelectSearchComponent),
7821
- multi: true,
7822
- },
7823
- ], template: `
7824
- <div class="multi-select-container" (click)="toggleDropdown($event)">
7825
- <!-- Main input display -->
7826
- <ion-input
7827
- #mainInput
7828
- type="text"
7829
- [value]="displayValue"
7830
- [placeholder]="props?.placeholder || placeholder"
7831
- readonly
7832
- class="main-input"
7833
- [class.is-open]="isOpen"
7834
- />
7835
-
7836
- <!-- Dropdown icon -->
7837
- <ion-icon name="chevron-down-outline" class="dropdown-icon" [class.rotated]="isOpen"></ion-icon>
7838
-
7839
- <!-- Hidden input for form control -->
7840
- <ion-input
7841
- style="position: absolute; opacity: 0; pointer-events: none;"
7842
- [formControl]="props?.control"
7843
- type="hidden"
7844
- />
7845
- </div>
7846
-
7847
- <!-- Dropdown overlay -->
7848
- <div class="dropdown-overlay" [class.visible]="isOpen" #dropdown>
7849
- <!-- Search bar -->
7850
- <div class="search-container" *ngIf="props?.options && props.options.length > 5">
7851
- <ion-searchbar
7852
- #searchbar
7853
- [placeholder]="searchPlaceholder"
7854
- (ionInput)="onSearch($event)"
7855
- [value]="searchTerm"
7856
- show-clear-button="focus"
7857
- [debounce]="200"
7858
- ></ion-searchbar>
7859
- </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
+ />
7860
7853
 
7861
- <!-- Debug button -->
7862
- <div class="search-container" style="background: red; color: white; padding: 4px;">
7863
- <button (click)="debugOptions()">DEBUG: {{ filteredOptions.length }} opciones</button>
7864
- </div>
7865
-
7866
- <!-- Action buttons -->
7867
- <div class="actions-container" *ngIf="filteredOptions.length > 0">
7868
- <ion-button fill="clear" size="small" (click)="selectAll()" [disabled]="filteredOptions.length === 0">
7869
- Seleccionar todos
7870
- </ion-button>
7871
- <ion-button
7872
- fill="clear"
7873
- size="small"
7874
- color="medium"
7875
- (click)="clearAll()"
7876
- [disabled]="selectedValues.length === 0"
7877
- >
7878
- Limpiar
7879
- </ion-button>
7880
- </div>
7854
+ <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
7881
7855
 
7882
- <!-- Options list -->
7883
- <div class="options-container">
7884
- <ion-list class="options-list">
7885
- <ion-item
7886
- *ngFor="let option of filteredOptions; trackBy: trackByFn"
7887
- button
7888
- (click)="toggleOption(option)"
7889
- class="option-item"
7890
- >
7891
- <ion-checkbox slot="start" [checked]="isSelected(option)"></ion-checkbox>
7892
- <ion-label>{{ option[labelProperty] }}</ion-label>
7893
- </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>
7894
7896
 
7895
- <!-- No results message -->
7896
- <ion-item *ngIf="filteredOptions.length === 0" class="no-results">
7897
- <ion-label color="medium">
7898
- {{ searchTerm ? 'No se encontraron resultados' : 'No hay opciones disponibles' }}
7899
- </ion-label>
7900
- </ion-item>
7901
- </ion-list>
7902
- </div>
7903
- </div>
7904
- `, 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"] }]
7905
- }], ctorParameters: () => [], propDecorators: { dropdownRef: [{
7906
- type: ViewChild,
7907
- args: ['dropdown']
7908
- }], 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: [{
7909
7914
  type: ViewChild,
7910
- args: ['mainInput']
7911
- }], props: [{
7915
+ args: ['modal']
7916
+ }], label: [{
7912
7917
  type: Input
7913
7918
  }], labelProperty: [{
7914
7919
  type: Input
@@ -7916,6 +7921,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7916
7921
  type: Input
7917
7922
  }], placeholder: [{
7918
7923
  type: Input
7924
+ }], props: [{
7925
+ type: Input
7919
7926
  }] } });
7920
7927
 
7921
7928
  class FormComponent {
@@ -8110,7 +8117,7 @@ class FormComponent {
8110
8117
  ></val-button-group>
8111
8118
  </form>
8112
8119
  </div>
8113
- `, 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"] }] }); }
8114
8121
  }
8115
8122
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormComponent, decorators: [{
8116
8123
  type: Component,