valtech-components 2.0.536 → 2.0.538

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.
@@ -4243,6 +4243,7 @@ class CountdownComponent {
4243
4243
  constructor() {
4244
4244
  this.complete = new EventEmitter();
4245
4245
  this.tick = new EventEmitter();
4246
+ this.i18n = inject(I18nService);
4246
4247
  this.time = {
4247
4248
  days: 0,
4248
4249
  hours: 0,
@@ -4375,7 +4376,7 @@ class CountdownComponent {
4375
4376
  return labels[unit] || unit;
4376
4377
  }
4377
4378
  getExpiredMessage() {
4378
- return this.props.expiredMessage || 'Tiempo agotado';
4379
+ return this.props.expiredMessage || this.i18n.t('timeExpired');
4379
4380
  }
4380
4381
  getColor() {
4381
4382
  if (this.props.color) {
@@ -5905,7 +5906,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5905
5906
  * @input props: InputMetadata - Configuration for the input (form control, errors, etc.)
5906
5907
  */
5907
5908
  class HintComponent {
5908
- constructor() { }
5909
+ constructor() {
5910
+ this.i18n = inject(I18nService);
5911
+ }
5909
5912
  ngOnInit() { }
5910
5913
  get shouldShowErrors() {
5911
5914
  if (this.props.control) {
@@ -5930,8 +5933,8 @@ class HintComponent {
5930
5933
  }
5931
5934
  else if (this.props.fromControl && this.props.toControl) {
5932
5935
  // NUMBER_FROM_TO field - check both controls
5933
- const fromLabel = this.props.fromLabel || 'Inicial';
5934
- const toLabel = this.props.toLabel || 'Final';
5936
+ const fromLabel = this.props.fromLabel || this.i18n.t('from');
5937
+ const toLabel = this.props.toLabel || this.i18n.t('to');
5935
5938
  if (this.props.fromControl.hasError(e)) {
5936
5939
  errors.push(`${fromLabel}: ${this.props.errors[e]}`);
5937
5940
  }
@@ -7079,7 +7082,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7079
7082
  * @input props: NumberFromToMetadata - Configuration for the number range input.
7080
7083
  */
7081
7084
  class NumberFromToComponent {
7082
- constructor() { }
7085
+ /** Get from label with i18n fallback */
7086
+ getFromLabel() {
7087
+ return this.props.fromLabel || this.i18n.t('from');
7088
+ }
7089
+ /** Get to label with i18n fallback */
7090
+ getToLabel() {
7091
+ return this.props.toLabel || this.i18n.t('to');
7092
+ }
7093
+ constructor() {
7094
+ this.i18n = inject(I18nService);
7095
+ }
7083
7096
  ngOnInit() {
7084
7097
  // Apply default values if configured
7085
7098
  if (this.props?.withDefault || this.props?.value) {
@@ -7140,7 +7153,7 @@ class NumberFromToComponent {
7140
7153
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NumberFromToComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7141
7154
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NumberFromToComponent, isStandalone: true, selector: "val-number-from-to", inputs: { props: "props" }, ngImport: i0, template: `
7142
7155
  <div class="number-from-to-container">
7143
- <ion-label position="stacked">{{ props.fromLabel || 'Inicial' }}</ion-label>
7156
+ <ion-label position="stacked">{{ getFromLabel() }}</ion-label>
7144
7157
  <ion-input
7145
7158
  [formControl]="fromControl"
7146
7159
  type="number"
@@ -7151,7 +7164,7 @@ class NumberFromToComponent {
7151
7164
  >
7152
7165
  </ion-input>
7153
7166
 
7154
- <ion-label position="stacked">{{ props.toLabel || 'Final' }}</ion-label>
7167
+ <ion-label position="stacked">{{ getToLabel() }}</ion-label>
7155
7168
  <ion-input
7156
7169
  [formControl]="toControl"
7157
7170
  type="number"
@@ -7168,7 +7181,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7168
7181
  type: Component,
7169
7182
  args: [{ selector: 'val-number-from-to', standalone: true, imports: [ReactiveFormsModule, IonInput, IonLabel], template: `
7170
7183
  <div class="number-from-to-container">
7171
- <ion-label position="stacked">{{ props.fromLabel || 'Inicial' }}</ion-label>
7184
+ <ion-label position="stacked">{{ getFromLabel() }}</ion-label>
7172
7185
  <ion-input
7173
7186
  [formControl]="fromControl"
7174
7187
  type="number"
@@ -7179,7 +7192,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7179
7192
  >
7180
7193
  </ion-input>
7181
7194
 
7182
- <ion-label position="stacked">{{ props.toLabel || 'Final' }}</ion-label>
7195
+ <ion-label position="stacked">{{ getToLabel() }}</ion-label>
7183
7196
  <ion-input
7184
7197
  [formControl]="toControl"
7185
7198
  type="number"
@@ -12605,8 +12618,17 @@ class NumberStepperComponent {
12605
12618
  constructor() {
12606
12619
  this.valueChange = new EventEmitter();
12607
12620
  this.states = ComponentStates;
12621
+ this.i18n = inject(I18nService);
12608
12622
  this.valueSubscription = null;
12609
12623
  }
12624
+ /** Get decrement button aria-label with i18n fallback */
12625
+ getDecrementLabel() {
12626
+ return this.props.decrementLabel || this.i18n.t('decrease');
12627
+ }
12628
+ /** Get increment button aria-label with i18n fallback */
12629
+ getIncrementLabel() {
12630
+ return this.props.incrementLabel || this.i18n.t('increase');
12631
+ }
12610
12632
  ngOnInit() {
12611
12633
  // Ensure initial value is within bounds
12612
12634
  this.clampValue();
@@ -12747,7 +12769,7 @@ class NumberStepperComponent {
12747
12769
  [shape]="props.buttonShape || 'round'"
12748
12770
  [disabled]="isAtMin || props.state === states.DISABLED"
12749
12771
  (click)="decrement()"
12750
- [attr.aria-label]="props.decrementLabel || 'Disminuir'"
12772
+ [attr.aria-label]="getDecrementLabel()"
12751
12773
  >
12752
12774
  <ion-icon slot="icon-only" name="remove-outline"></ion-icon>
12753
12775
  </ion-button>
@@ -12780,7 +12802,7 @@ class NumberStepperComponent {
12780
12802
  [shape]="props.buttonShape || 'round'"
12781
12803
  [disabled]="isAtMax || props.state === states.DISABLED"
12782
12804
  (click)="increment()"
12783
- [attr.aria-label]="props.incrementLabel || 'Aumentar'"
12805
+ [attr.aria-label]="getIncrementLabel()"
12784
12806
  >
12785
12807
  <ion-icon slot="icon-only" name="add-outline"></ion-icon>
12786
12808
  </ion-button>
@@ -12847,7 +12869,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
12847
12869
  [shape]="props.buttonShape || 'round'"
12848
12870
  [disabled]="isAtMin || props.state === states.DISABLED"
12849
12871
  (click)="decrement()"
12850
- [attr.aria-label]="props.decrementLabel || 'Disminuir'"
12872
+ [attr.aria-label]="getDecrementLabel()"
12851
12873
  >
12852
12874
  <ion-icon slot="icon-only" name="remove-outline"></ion-icon>
12853
12875
  </ion-button>
@@ -12880,7 +12902,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
12880
12902
  [shape]="props.buttonShape || 'round'"
12881
12903
  [disabled]="isAtMax || props.state === states.DISABLED"
12882
12904
  (click)="increment()"
12883
- [attr.aria-label]="props.incrementLabel || 'Aumentar'"
12905
+ [attr.aria-label]="getIncrementLabel()"
12884
12906
  >
12885
12907
  <ion-icon slot="icon-only" name="add-outline"></ion-icon>
12886
12908
  </ion-button>
@@ -32777,8 +32799,9 @@ class DocsTocComponent {
32777
32799
  // Reactive state
32778
32800
  this.activeId = signal('');
32779
32801
  this.flatItems = signal([]);
32780
- this.observer = null;
32781
32802
  this.headingElements = [];
32803
+ this.scrollHandler = null;
32804
+ this.rafId = null;
32782
32805
  }
32783
32806
  ngOnInit() {
32784
32807
  this.updateFlatItems();
@@ -32868,34 +32891,57 @@ class DocsTocComponent {
32868
32891
  .filter((el) => el !== null);
32869
32892
  if (this.headingElements.length === 0)
32870
32893
  return;
32871
- const offsetTop = this.props.offsetTop ?? 100;
32872
- // Use IntersectionObserver for scroll spy
32894
+ // Set initial active item
32895
+ this.updateActiveHeading();
32896
+ // Use scroll event with requestAnimationFrame for performance
32873
32897
  this.ngZone.runOutsideAngular(() => {
32874
- this.observer = new IntersectionObserver(entries => {
32875
- // Find the first visible heading
32876
- const visibleEntries = entries
32877
- .filter(entry => entry.isIntersecting)
32878
- .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
32879
- if (visibleEntries.length > 0) {
32880
- const activeEntry = visibleEntries[0];
32881
- this.ngZone.run(() => {
32882
- this.activeId.set(activeEntry.target.id);
32883
- this.sectionChange.emit(activeEntry.target.id);
32884
- });
32898
+ this.scrollHandler = () => {
32899
+ if (this.rafId) {
32900
+ cancelAnimationFrame(this.rafId);
32885
32901
  }
32886
- }, {
32887
- rootMargin: `-${offsetTop}px 0px -70% 0px`,
32888
- threshold: 0,
32889
- });
32890
- this.headingElements.forEach(el => {
32891
- this.observer?.observe(el);
32892
- });
32902
+ this.rafId = requestAnimationFrame(() => {
32903
+ this.updateActiveHeading();
32904
+ });
32905
+ };
32906
+ window.addEventListener('scroll', this.scrollHandler, { passive: true });
32893
32907
  });
32894
32908
  }
32909
+ updateActiveHeading() {
32910
+ const offsetTop = this.props.offsetTop ?? 100;
32911
+ const scrollY = window.scrollY;
32912
+ // Find the heading that is currently at or above the offset point
32913
+ let activeHeading = null;
32914
+ for (const heading of this.headingElements) {
32915
+ const rect = heading.getBoundingClientRect();
32916
+ const headingTop = rect.top + scrollY;
32917
+ // If heading is at or above the trigger point (scrollY + offset)
32918
+ if (headingTop <= scrollY + offsetTop + 10) {
32919
+ activeHeading = heading;
32920
+ }
32921
+ else {
32922
+ // Headings are in order, so we can stop once we find one below
32923
+ break;
32924
+ }
32925
+ }
32926
+ // If no heading is above the trigger point, use the first one
32927
+ if (!activeHeading && this.headingElements.length > 0) {
32928
+ activeHeading = this.headingElements[0];
32929
+ }
32930
+ if (activeHeading && activeHeading.id !== this.activeId()) {
32931
+ this.ngZone.run(() => {
32932
+ this.activeId.set(activeHeading.id);
32933
+ this.sectionChange.emit(activeHeading.id);
32934
+ });
32935
+ }
32936
+ }
32895
32937
  destroyScrollSpy() {
32896
- if (this.observer) {
32897
- this.observer.disconnect();
32898
- this.observer = null;
32938
+ if (this.scrollHandler) {
32939
+ window.removeEventListener('scroll', this.scrollHandler);
32940
+ this.scrollHandler = null;
32941
+ }
32942
+ if (this.rafId) {
32943
+ cancelAnimationFrame(this.rafId);
32944
+ this.rafId = null;
32899
32945
  }
32900
32946
  this.headingElements = [];
32901
32947
  }