igniteui-angular 19.2.27 → 19.2.29

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,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, HostListener, Input, Directive, EventEmitter, InjectionToken, isDevMode, inject, PLATFORM_ID, Inject, ElementRef, ViewContainerRef, createComponent, HostBinding, Output, Self, Optional, booleanAttribute, SecurityContext, DestroyRef, Component, ContentChild, ContentChildren, RendererStyleFlags2, Pipe, ViewChild, Renderer2, NgZone, signal, QueryList, effect, LOCALE_ID, forwardRef, Host, ViewChildren, TemplateRef, ChangeDetectionStrategy, SimpleChange, ChangeDetectorRef, SkipSelf, CUSTOM_ELEMENTS_SCHEMA, reflectComponentType, NgModule } from '@angular/core';
3
3
  import * as i4 from '@angular/forms';
4
- import { NgModel, NgControl, FormControlName, NG_VALUE_ACCESSOR, Validators, NG_VALIDATORS, FormGroup, FormsModule, RequiredValidator, MinValidator, MaxValidator, EmailValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, FormControl, ReactiveFormsModule } from '@angular/forms';
5
- import { Observable, NEVER, Subject, fromEvent, BehaviorSubject, interval, animationFrameScheduler, noop, takeUntil as takeUntil$1, merge, Subscription, timer, sampleTime, filter as filter$1, pipe, take as take$1 } from 'rxjs';
4
+ import { TouchedChangeEvent, NgModel, NgControl, FormControlName, NG_VALUE_ACCESSOR, Validators, NG_VALIDATORS, FormGroup, FormsModule, RequiredValidator, MinValidator, MaxValidator, EmailValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, FormControl, ReactiveFormsModule } from '@angular/forms';
5
+ import { Observable, NEVER, Subject, fromEvent, BehaviorSubject, filter as filter$1, interval, animationFrameScheduler, noop, takeUntil as takeUntil$1, merge, Subscription, timer, sampleTime, pipe, take as take$1 } from 'rxjs';
6
6
  import { takeUntil, filter, throttle, throttleTime, first as first$2, take, debounce, tap, switchMap, skipLast, map, debounceTime, shareReplay, takeWhile, timeout, pluck } from 'rxjs/operators';
7
7
  import { isPlatformBrowser, formatDate as formatDate$1, CurrencyPipe, FormatWidth, getLocaleDateFormat, formatPercent, formatNumber, getLocaleCurrencyCode, DatePipe, getLocaleDateTimeFormat, DOCUMENT, NgTemplateOutlet, NgClass, TitleCasePipe, getLocaleFirstDayOfWeek, NgStyle, getLocaleCurrencySymbol, formatCurrency as formatCurrency$1, getLocaleNumberFormat, NumberFormatStyle, DecimalPipe, PercentPipe, getCurrencySymbol, AsyncPipe } from '@angular/common';
8
8
  import { mergeWith, isEqual as isEqual$1 } from 'lodash-es';
@@ -9973,6 +9973,11 @@ class IgxInputDirective {
9973
9973
  if (this.ngControl) {
9974
9974
  this._statusChanges$ = this.ngControl.statusChanges.subscribe(this.onStatusChanged.bind(this));
9975
9975
  this._valueChanges$ = this.ngControl.valueChanges.subscribe(this.onValueChanged.bind(this));
9976
+ if (this.ngControl.control) {
9977
+ this._touchedChanges$ = this.ngControl.control.events
9978
+ .pipe(filter$1(e => e instanceof TouchedChangeEvent))
9979
+ .subscribe(this.updateValidityState.bind(this));
9980
+ }
9976
9981
  }
9977
9982
  this.cdr.detectChanges();
9978
9983
  }
@@ -9984,6 +9989,9 @@ class IgxInputDirective {
9984
9989
  if (this._valueChanges$) {
9985
9990
  this._valueChanges$.unsubscribe();
9986
9991
  }
9992
+ if (this._touchedChanges$) {
9993
+ this._touchedChanges$.unsubscribe();
9994
+ }
9987
9995
  }
9988
9996
  /**
9989
9997
  * Sets a focus on the igxInput.
@@ -52547,11 +52555,11 @@ class IgxExcelStyleConditionalFilterComponent {
52547
52555
  return this.esf.column.filters.conditionList();
52548
52556
  }
52549
52557
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: IgxExcelStyleConditionalFilterComponent, deps: [{ token: BaseFilteringComponent }, { token: PlatformUtil }], target: i0.ɵɵFactoryTarget.Component }); }
52550
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: IgxExcelStyleConditionalFilterComponent, isStandalone: true, selector: "igx-excel-style-conditional-filter", viewQueries: [{ propertyName: "customDialog", first: true, predicate: ["customDialog"], descendants: true, read: IgxExcelStyleCustomDialogComponent }, { propertyName: "subMenu", first: true, predicate: ["subMenu"], descendants: true, read: IgxDropDownComponent }], ngImport: i0, template: "@if (esf.column) {\n <div tabindex=\"0\"\n class=\"igx-excel-filter__actions-filter\"\n [ngClass]=\"filterNumber > 0 ? 'igx-excel-filter__actions-filter--active' : ''\"\n (keydown)=\"onTextFilterKeyDown($event)\"\n (click)=\"onTextFilterClick($event)\"\n [igxDropDownItemNavigation]=\"subMenu\"\n role=\"menuitem\"\n aria-haspopup=\"true\"\n [attr.aria-controls]=\"this.subMenu?.listId\"\n [attr.aria-activedescendant]=\"!this.subMenu?.collapsed ? this.subMenu?.focusedItem?.id : null\">\n <span class=\"igx-excel-filter__filter-number\">\n {{ subMenuText }}\n @if (filterNumber > 0) { ({{filterNumber}}) }\n </span>\n <igx-icon name=\"chevron_right\" family=\"default\"></igx-icon>\n </div>\n\n <igx-drop-down\n #subMenu\n [maxHeight]=\"'397px'\"\n (selectionChanging)=\"onSubMenuSelection($event)\"\n (closed)=\"onSubMenuClosed()\">\n <div>\n @for (condition of conditions; track condition) {\n <igx-drop-down-item\n [selected]=\"getSelectedCondition(condition)\"\n [value]=\"condition\">\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon family=\"default\" [name]=\"getCondition(condition).iconName\"></igx-icon>\n <span class=\"igx-grid__filtering-dropdown-text\">{{ translateCondition(condition) }}</span>\n </div>\n </igx-drop-down-item>\n }\n @if (showCustomFilterItem()) {\n <igx-drop-down-item\n [selected]=\"getSelectedCondition('custom')\" >\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon name=\"filter_list\" family=\"default\"></igx-icon>\n <span class=\"igx-grid__filtering-dropdown-text\">{{ esf.grid.resourceStrings.igx_grid_excel_custom_filter }}</span>\n </div>\n </igx-drop-down-item>\n }\n </div>\n </igx-drop-down>\n\n <igx-excel-style-custom-dialog\n #customDialog\n [column]=\"esf.column\"\n [filteringService]=\"esf.grid.filteringService\"\n [overlayComponentId]=\"esf.overlayComponentId\">\n </igx-excel-style-custom-dialog>\n}\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: IgxDropDownItemNavigationDirective, selector: "[igxDropDownItemNavigation]", inputs: ["igxDropDownItemNavigation"] }, { kind: "component", type: IgxIconComponent, selector: "igx-icon", inputs: ["ariaHidden", "family", "name", "active"] }, { kind: "component", type: IgxDropDownComponent, selector: "igx-drop-down", inputs: ["allowItemsFocus", "labelledBy"], outputs: ["opening", "opened", "closing", "closed"] }, { kind: "component", type: IgxDropDownItemComponent, selector: "igx-drop-down-item" }, { kind: "component", type: IgxExcelStyleCustomDialogComponent, selector: "igx-excel-style-custom-dialog", inputs: ["expressionsList", "column", "selectedOperator", "filteringService", "overlayComponentId"] }] }); }
52558
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: IgxExcelStyleConditionalFilterComponent, isStandalone: true, selector: "igx-excel-style-conditional-filter", viewQueries: [{ propertyName: "customDialog", first: true, predicate: ["customDialog"], descendants: true, read: IgxExcelStyleCustomDialogComponent }, { propertyName: "subMenu", first: true, predicate: ["subMenu"], descendants: true, read: IgxDropDownComponent }], ngImport: i0, template: "@if (esf.column) {\n <div tabindex=\"0\"\n class=\"igx-excel-filter__actions-filter\"\n [ngClass]=\"filterNumber > 0 ? 'igx-excel-filter__actions-filter--active' : ''\"\n (keydown)=\"onTextFilterKeyDown($event)\"\n (click)=\"onTextFilterClick($event)\"\n [igxDropDownItemNavigation]=\"subMenu\"\n role=\"menuitem\"\n aria-haspopup=\"true\"\n [attr.aria-controls]=\"subMenu?.listId\"\n [attr.aria-activedescendant]=\"!subMenu?.collapsed ? subMenu?.focusedItem?.id : null\">\n <span class=\"igx-excel-filter__filter-number\">\n {{ subMenuText }}\n @if (filterNumber > 0) { ({{filterNumber}}) }\n </span>\n <igx-icon name=\"chevron_right\" family=\"default\"></igx-icon>\n </div>\n\n <igx-drop-down\n #subMenu\n [maxHeight]=\"'397px'\"\n (selectionChanging)=\"onSubMenuSelection($event)\"\n (closed)=\"onSubMenuClosed()\">\n <div>\n @for (condition of conditions; track condition) {\n <igx-drop-down-item\n [selected]=\"getSelectedCondition(condition)\"\n [value]=\"condition\">\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon family=\"default\" [name]=\"getCondition(condition).iconName\"></igx-icon>\n <span class=\"igx-grid__filtering-dropdown-text\">{{ translateCondition(condition) }}</span>\n </div>\n </igx-drop-down-item>\n }\n @if (showCustomFilterItem()) {\n <igx-drop-down-item\n [selected]=\"getSelectedCondition('custom')\" >\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon name=\"filter_list\" family=\"default\"></igx-icon>\n <span class=\"igx-grid__filtering-dropdown-text\">{{ esf.grid.resourceStrings.igx_grid_excel_custom_filter }}</span>\n </div>\n </igx-drop-down-item>\n }\n </div>\n </igx-drop-down>\n\n <igx-excel-style-custom-dialog\n #customDialog\n [column]=\"esf.column\"\n [filteringService]=\"esf.grid.filteringService\"\n [overlayComponentId]=\"esf.overlayComponentId\">\n </igx-excel-style-custom-dialog>\n}\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: IgxDropDownItemNavigationDirective, selector: "[igxDropDownItemNavigation]", inputs: ["igxDropDownItemNavigation"] }, { kind: "component", type: IgxIconComponent, selector: "igx-icon", inputs: ["ariaHidden", "family", "name", "active"] }, { kind: "component", type: IgxDropDownComponent, selector: "igx-drop-down", inputs: ["allowItemsFocus", "labelledBy"], outputs: ["opening", "opened", "closing", "closed"] }, { kind: "component", type: IgxDropDownItemComponent, selector: "igx-drop-down-item" }, { kind: "component", type: IgxExcelStyleCustomDialogComponent, selector: "igx-excel-style-custom-dialog", inputs: ["expressionsList", "column", "selectedOperator", "filteringService", "overlayComponentId"] }] }); }
52551
52559
  }
52552
52560
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: IgxExcelStyleConditionalFilterComponent, decorators: [{
52553
52561
  type: Component,
52554
- args: [{ selector: 'igx-excel-style-conditional-filter', imports: [NgClass, IgxDropDownItemNavigationDirective, IgxIconComponent, IgxDropDownComponent, IgxDropDownItemComponent, IgxExcelStyleCustomDialogComponent], template: "@if (esf.column) {\n <div tabindex=\"0\"\n class=\"igx-excel-filter__actions-filter\"\n [ngClass]=\"filterNumber > 0 ? 'igx-excel-filter__actions-filter--active' : ''\"\n (keydown)=\"onTextFilterKeyDown($event)\"\n (click)=\"onTextFilterClick($event)\"\n [igxDropDownItemNavigation]=\"subMenu\"\n role=\"menuitem\"\n aria-haspopup=\"true\"\n [attr.aria-controls]=\"this.subMenu?.listId\"\n [attr.aria-activedescendant]=\"!this.subMenu?.collapsed ? this.subMenu?.focusedItem?.id : null\">\n <span class=\"igx-excel-filter__filter-number\">\n {{ subMenuText }}\n @if (filterNumber > 0) { ({{filterNumber}}) }\n </span>\n <igx-icon name=\"chevron_right\" family=\"default\"></igx-icon>\n </div>\n\n <igx-drop-down\n #subMenu\n [maxHeight]=\"'397px'\"\n (selectionChanging)=\"onSubMenuSelection($event)\"\n (closed)=\"onSubMenuClosed()\">\n <div>\n @for (condition of conditions; track condition) {\n <igx-drop-down-item\n [selected]=\"getSelectedCondition(condition)\"\n [value]=\"condition\">\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon family=\"default\" [name]=\"getCondition(condition).iconName\"></igx-icon>\n <span class=\"igx-grid__filtering-dropdown-text\">{{ translateCondition(condition) }}</span>\n </div>\n </igx-drop-down-item>\n }\n @if (showCustomFilterItem()) {\n <igx-drop-down-item\n [selected]=\"getSelectedCondition('custom')\" >\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon name=\"filter_list\" family=\"default\"></igx-icon>\n <span class=\"igx-grid__filtering-dropdown-text\">{{ esf.grid.resourceStrings.igx_grid_excel_custom_filter }}</span>\n </div>\n </igx-drop-down-item>\n }\n </div>\n </igx-drop-down>\n\n <igx-excel-style-custom-dialog\n #customDialog\n [column]=\"esf.column\"\n [filteringService]=\"esf.grid.filteringService\"\n [overlayComponentId]=\"esf.overlayComponentId\">\n </igx-excel-style-custom-dialog>\n}\n" }]
52562
+ args: [{ selector: 'igx-excel-style-conditional-filter', imports: [NgClass, IgxDropDownItemNavigationDirective, IgxIconComponent, IgxDropDownComponent, IgxDropDownItemComponent, IgxExcelStyleCustomDialogComponent], template: "@if (esf.column) {\n <div tabindex=\"0\"\n class=\"igx-excel-filter__actions-filter\"\n [ngClass]=\"filterNumber > 0 ? 'igx-excel-filter__actions-filter--active' : ''\"\n (keydown)=\"onTextFilterKeyDown($event)\"\n (click)=\"onTextFilterClick($event)\"\n [igxDropDownItemNavigation]=\"subMenu\"\n role=\"menuitem\"\n aria-haspopup=\"true\"\n [attr.aria-controls]=\"subMenu?.listId\"\n [attr.aria-activedescendant]=\"!subMenu?.collapsed ? subMenu?.focusedItem?.id : null\">\n <span class=\"igx-excel-filter__filter-number\">\n {{ subMenuText }}\n @if (filterNumber > 0) { ({{filterNumber}}) }\n </span>\n <igx-icon name=\"chevron_right\" family=\"default\"></igx-icon>\n </div>\n\n <igx-drop-down\n #subMenu\n [maxHeight]=\"'397px'\"\n (selectionChanging)=\"onSubMenuSelection($event)\"\n (closed)=\"onSubMenuClosed()\">\n <div>\n @for (condition of conditions; track condition) {\n <igx-drop-down-item\n [selected]=\"getSelectedCondition(condition)\"\n [value]=\"condition\">\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon family=\"default\" [name]=\"getCondition(condition).iconName\"></igx-icon>\n <span class=\"igx-grid__filtering-dropdown-text\">{{ translateCondition(condition) }}</span>\n </div>\n </igx-drop-down-item>\n }\n @if (showCustomFilterItem()) {\n <igx-drop-down-item\n [selected]=\"getSelectedCondition('custom')\" >\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon name=\"filter_list\" family=\"default\"></igx-icon>\n <span class=\"igx-grid__filtering-dropdown-text\">{{ esf.grid.resourceStrings.igx_grid_excel_custom_filter }}</span>\n </div>\n </igx-drop-down-item>\n }\n </div>\n </igx-drop-down>\n\n <igx-excel-style-custom-dialog\n #customDialog\n [column]=\"esf.column\"\n [filteringService]=\"esf.grid.filteringService\"\n [overlayComponentId]=\"esf.overlayComponentId\">\n </igx-excel-style-custom-dialog>\n}\n" }]
52555
52563
  }], ctorParameters: () => [{ type: BaseFilteringComponent }, { type: PlatformUtil }], propDecorators: { customDialog: [{
52556
52564
  type: ViewChild,
52557
52565
  args: ['customDialog', { read: IgxExcelStyleCustomDialogComponent }]
@@ -63384,6 +63392,11 @@ class IgxGridNavigationService {
63384
63392
  this._activeNode = {};
63385
63393
  this.lastActiveNode = {};
63386
63394
  this.pendingNavigation = false;
63395
+ this.keydownNotify = new Subject();
63396
+ this.keydownNotify.pipe(throttleTime(30, animationFrameScheduler))
63397
+ .subscribe((event) => {
63398
+ this.dispatchEvent(event);
63399
+ });
63387
63400
  }
63388
63401
  handleNavigation(event) {
63389
63402
  const key = event.key.toLowerCase();
@@ -63397,7 +63410,7 @@ class IgxGridNavigationService {
63397
63410
  event.preventDefault();
63398
63411
  }
63399
63412
  if (event.repeat) {
63400
- setTimeout(() => this.dispatchEvent(event), 1);
63413
+ this.keydownNotify.next(event);
63401
63414
  }
63402
63415
  else {
63403
63416
  this.dispatchEvent(event);
@@ -63432,10 +63445,8 @@ class IgxGridNavigationService {
63432
63445
  event.preventDefault();
63433
63446
  this.navigateInBody(position.rowIndex, position.colIndex, (obj) => {
63434
63447
  obj.target.activate(event);
63435
- this.grid.cdr.detectChanges();
63436
63448
  });
63437
63449
  }
63438
- this.grid.cdr.detectChanges();
63439
63450
  }
63440
63451
  summaryNav(event) {
63441
63452
  if (this.grid.hasSummarizedColumns) {
@@ -63477,7 +63488,6 @@ class IgxGridNavigationService {
63477
63488
  this.grid.clearCellSelection();
63478
63489
  this.grid.navigateTo(this.activeNode.row, this.activeNode.column, (obj) => {
63479
63490
  obj.target?.activate(event);
63480
- this.grid.cdr.detectChanges();
63481
63491
  });
63482
63492
  }
63483
63493
  else {
@@ -63905,7 +63915,6 @@ class IgxGridNavigationService {
63905
63915
  }
63906
63916
  this.navigateInBody(next.rowIndex, next.visibleColumnIndex, (obj) => {
63907
63917
  obj.target.activate(event);
63908
- this.grid.cdr.detectChanges();
63909
63918
  });
63910
63919
  }
63911
63920
  navigateInBody(rowIndex, visibleColIndex, cb = null) {
@@ -83839,27 +83848,36 @@ class IgxTreeGridHierarchizingPipe {
83839
83848
  getRowID(primaryKey, rowData) {
83840
83849
  return primaryKey ? rowData[primaryKey] : rowData;
83841
83850
  }
83851
+ /**
83852
+ * Converts a flat array of data into a hierarchical (tree) structure,
83853
+ * preserving the original order of the records among siblings.
83854
+ *
83855
+ * It uses a two-pass approach:
83856
+ * 1. Creates all ITreeGridRecord objects and populates the Map for quick lookup.
83857
+ * 2. Links the records by iterating again, ensuring children are added to
83858
+ * their parent's children array in the order they appeared in the
83859
+ * original collection.
83860
+ *
83861
+ * @param collection The flat array of data to be hierarchized. This is the array whose order should be preserved.
83862
+ * @param primaryKey The name of the property in the data objects that serves as the unique identifier (e.g., 'id').
83863
+ * @param foreignKey The name of the property in the data objects that links to the parent's primary key (e.g., 'parentId').
83864
+ * @param map A pre-existing Map object (key: primaryKey value, value: ITreeGridRecord) used to store and quickly look up all created records.
83865
+ * @param flatData The original flat data array. Used for passing to the setIndentationLevels method (not directly used for hierarchy building).
83866
+ * @returns An array of ITreeGridRecord objects representing the root nodes of the hierarchy, ordered as they appeared in the original collection.
83867
+ */
83842
83868
  hierarchizeFlatData(collection, primaryKey, foreignKey, map, flatData) {
83843
- const result = [];
83844
- const missingParentRecords = [];
83845
83869
  collection.forEach(row => {
83846
83870
  const record = {
83847
83871
  key: this.getRowID(primaryKey, row),
83848
83872
  data: row,
83849
83873
  children: []
83850
83874
  };
83851
- const parent = map.get(row[foreignKey]);
83852
- if (parent) {
83853
- record.parent = parent;
83854
- parent.children.push(record);
83855
- }
83856
- else {
83857
- missingParentRecords.push(record);
83858
- }
83859
83875
  map.set(row[primaryKey], record);
83860
83876
  });
83861
- missingParentRecords.forEach(record => {
83862
- const parent = map.get(record.data[foreignKey]);
83877
+ const result = [];
83878
+ collection.forEach(row => {
83879
+ const record = map.get(row[primaryKey]);
83880
+ const parent = map.get(row[foreignKey]);
83863
83881
  if (parent) {
83864
83882
  record.parent = parent;
83865
83883
  parent.children.push(record);