igniteui-angular 12.1.4 → 12.1.8

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.
Files changed (41) hide show
  1. package/bundles/igniteui-angular.umd.js +371 -65
  2. package/bundles/igniteui-angular.umd.js.map +1 -1
  3. package/esm2015/lib/core/i18n/resources.js +10 -1
  4. package/esm2015/lib/core/utils.js +2 -1
  5. package/esm2015/lib/date-picker/date-picker.component.js +9 -3
  6. package/esm2015/lib/directives/drag-drop/drag-drop.directive.js +8 -2
  7. package/esm2015/lib/directives/notification/notifications.directive.js +1 -1
  8. package/esm2015/lib/grids/api.service.js +25 -1
  9. package/esm2015/lib/grids/columns/column.component.js +5 -3
  10. package/esm2015/lib/grids/common/crud.service.js +4 -3
  11. package/esm2015/lib/grids/filtering/base/grid-filtering-row.component.js +2 -2
  12. package/esm2015/lib/grids/filtering/excel-style/excel-style-clear-filters.component.js +2 -2
  13. package/esm2015/lib/grids/filtering/excel-style/excel-style-conditional-filter.component.js +2 -2
  14. package/esm2015/lib/grids/filtering/excel-style/excel-style-hiding.component.js +2 -2
  15. package/esm2015/lib/grids/filtering/excel-style/excel-style-pinning.component.js +2 -2
  16. package/esm2015/lib/grids/filtering/excel-style/excel-style-selecting.component.js +2 -2
  17. package/esm2015/lib/grids/grid/grid.component.js +2 -1
  18. package/esm2015/lib/grids/grid/groupby-row.component.js +3 -2
  19. package/esm2015/lib/grids/grid-base.directive.js +99 -4
  20. package/esm2015/lib/grids/tree-grid/tree-grid-api.service.js +25 -1
  21. package/esm2015/lib/grids/tree-grid/tree-grid.component.js +26 -1
  22. package/esm2015/lib/snackbar/snackbar.component.js +63 -26
  23. package/esm2015/lib/tabs/tabs.directive.js +2 -5
  24. package/esm2015/lib/toast/toast.component.js +64 -11
  25. package/esm2015/public_api.js +1 -1
  26. package/fesm2015/igniteui-angular.js +332 -52
  27. package/fesm2015/igniteui-angular.js.map +1 -1
  28. package/igniteui-angular.metadata.json +1 -1
  29. package/lib/core/i18n/resources.d.ts +9 -0
  30. package/lib/core/utils.d.ts +1 -0
  31. package/lib/date-picker/date-picker.component.d.ts +3 -2
  32. package/lib/directives/notification/notifications.directive.d.ts +2 -2
  33. package/lib/grids/api.service.d.ts +14 -0
  34. package/lib/grids/grid-base.directive.d.ts +38 -2
  35. package/lib/grids/tree-grid/tree-grid-api.service.d.ts +14 -0
  36. package/lib/grids/tree-grid/tree-grid.component.d.ts +20 -0
  37. package/lib/snackbar/snackbar.component.d.ts +41 -2
  38. package/lib/tabs/tabs.directive.d.ts +0 -2
  39. package/lib/toast/toast.component.d.ts +40 -2
  40. package/package.json +1 -1
  41. package/public_api.d.ts +2 -0
@@ -1340,6 +1340,7 @@ const yieldingLoop = (count, chunkSize, callback, done) => {
1340
1340
  };
1341
1341
  chunk();
1342
1342
  };
1343
+ const isConstructor = (ref) => typeof ref === 'function' && Boolean(ref.prototype) && Boolean(ref.prototype.constructor);
1343
1344
  const reverseAnimationResolver = (animation) => { var _a; return (_a = oppositeAnimation.get(animation)) !== null && _a !== void 0 ? _a : animation; };
1344
1345
  const isHorizontalAnimation = (animation) => horizontalAnimations.includes(animation);
1345
1346
  const isVerticalAnimation = (animation) => verticalAnimations.includes(animation);
@@ -6397,8 +6398,8 @@ class IgxRowAddCrudState extends IgxRowCrudState {
6397
6398
  * @hidden @internal
6398
6399
  */
6399
6400
  createAddRowParent(row, newRowAsChild) {
6400
- const rowIndex = row ? row.index : this.grid.rowList.length - 1;
6401
- const rowId = row ? row.rowID : (rowIndex >= 0 ? this.grid.rowList.last.rowID : null);
6401
+ const rowIndex = row ? row.index : -1;
6402
+ const rowId = row ? row.rowID : null;
6402
6403
  const isInPinnedArea = this.grid.isRecordPinnedByViewIndex(rowIndex);
6403
6404
  const pinIndex = this.grid.pinnedRecords.findIndex(x => x[this.primaryKey] === rowId);
6404
6405
  const unpinIndex = this.grid.getUnpinnedIndexById(rowId);
@@ -6524,6 +6525,7 @@ class IgxGridCRUDService extends IgxRowAddCrudState {
6524
6525
  this.grid.navigateTo(this.row.index, -1);
6525
6526
  const dummyRow = this.grid.gridAPI.get_row_by_index(this.row.index);
6526
6527
  dummyRow.triggerAddAnimation();
6528
+ dummyRow.cdr.detectChanges();
6527
6529
  dummyRow.addAnimationEnd.pipe(first$1()).subscribe(() => {
6528
6530
  const cell = dummyRow.cells.find(c => c.editable);
6529
6531
  if (cell) {
@@ -6666,6 +6668,20 @@ class GridBaseAPIService {
6666
6668
  get_row_by_index(rowIndex) {
6667
6669
  return this.grid.rowList.find((row) => row.index === rowIndex);
6668
6670
  }
6671
+ /**
6672
+ * Gets the rowID of the record at the specified data view index
6673
+ *
6674
+ * @param index
6675
+ * @param dataCollection
6676
+ */
6677
+ get_rec_id_by_index(index, dataCollection) {
6678
+ dataCollection = dataCollection || this.grid.data;
6679
+ if (index >= 0 && index < dataCollection.length) {
6680
+ const rec = dataCollection[index];
6681
+ return this.grid.primaryKey ? rec[this.grid.primaryKey] : rec;
6682
+ }
6683
+ return null;
6684
+ }
6669
6685
  get_cell_by_key(rowSelector, field) {
6670
6686
  const row = this.get_row_by_key(rowSelector);
6671
6687
  if (row && row.cells) {
@@ -6925,6 +6941,16 @@ class GridBaseAPIService {
6925
6941
  get_rec_by_id(rowID) {
6926
6942
  return this.grid.primaryKey ? this.getRowData(rowID) : rowID;
6927
6943
  }
6944
+ /**
6945
+ * Returns the index of the record in the data view by pk or -1 if not found or primaryKey is not set.
6946
+ *
6947
+ * @param pk
6948
+ * @param dataCollection
6949
+ */
6950
+ get_rec_index_by_id(pk, dataCollection) {
6951
+ dataCollection = dataCollection || this.grid.data;
6952
+ return this.grid.primaryKey ? dataCollection.findIndex(rec => rec[this.grid.primaryKey] === pk) : -1;
6953
+ }
6928
6954
  allow_expansion_state_change(rowID, expanded) {
6929
6955
  return this.grid.expansionStates.get(rowID) !== expanded;
6930
6956
  }
@@ -9521,7 +9547,9 @@ class IgxColumnComponent {
9521
9547
  * @memberof IgxColumnComponent
9522
9548
  */
9523
9549
  set summaries(classRef) {
9524
- this._summaries = new classRef();
9550
+ if (isConstructor(classRef)) {
9551
+ this._summaries = new classRef();
9552
+ }
9525
9553
  if (this.grid) {
9526
9554
  this.grid.summaryService.removeSummariesCachePerColumn(this.field);
9527
9555
  this.grid.summaryPipeTrigger++;
@@ -19329,6 +19357,15 @@ const TreeResourceStringsEN = {
19329
19357
 
19330
19358
  /**
19331
19359
  * @hidden
19360
+ * IF YOU EDIT THIS OBJECT, DO NOT FORGET TO UPDATE
19361
+ * projects/igniteui-angular-i18n as well (create the appropriately named files,
19362
+ * containing the new/updated component string keys and EN strings for values + create a separate issue + pending-localization label)
19363
+ *
19364
+ * TODO Add automation tests:
19365
+ * 1) each of the folders/languages under \projects\igniteui-angular-i18n\src\ contain resources.ts file with matching components count.
19366
+ * \projects\igniteui-angular-i18n\src\BG\resources.ts contains IgxResourceStringsBG.count matching this.CurrentResourceStrings.count
19367
+ * 2) \igniteui-angular\projects\igniteui-angular\src\public_api.ts --> Check if the new interface is added
19368
+ * to IInputResourceStrings (just a proxy as it is later on imported in the angular-i18n package)
19332
19369
  */
19333
19370
  const CurrentResourceStrings = {
19334
19371
  GridResStrings: cloneValue(GridResourceStringsEN),
@@ -21150,7 +21187,13 @@ class IgxDragDirective {
21150
21187
  owner: this,
21151
21188
  originalEvent
21152
21189
  };
21153
- const elementsFromPoint = this.getElementsAtPoint(pageX, pageY);
21190
+ let elementsFromPoint = this.getElementsAtPoint(pageX, pageY);
21191
+ // Check for shadowRoot instance and use it if present
21192
+ for (const elFromPoint of elementsFromPoint) {
21193
+ if ((elFromPoint === null || elFromPoint === void 0 ? void 0 : elFromPoint.shadowRoot) !== null) {
21194
+ elementsFromPoint = elFromPoint.shadowRoot.elementsFromPoint(pageX, pageY);
21195
+ }
21196
+ }
21154
21197
  for (const element of elementsFromPoint) {
21155
21198
  if (element.getAttribute('droppable') === 'true' &&
21156
21199
  element !== this.ghostElement && element !== this.element.nativeElement) {
@@ -37042,7 +37085,7 @@ let NEXT_ID$b = 0;
37042
37085
  * ```
37043
37086
  */
37044
37087
  class IgxDatePickerComponent extends PickerBaseDirective {
37045
- constructor(element, _localeId, _overlayService, _moduleRef, _injector, _renderer, platform, _displayDensityOptions, _inputGroupType) {
37088
+ constructor(element, _localeId, _overlayService, _moduleRef, _injector, _renderer, platform, cdr, _displayDensityOptions, _inputGroupType) {
37046
37089
  super(element, _localeId, _displayDensityOptions, _inputGroupType);
37047
37090
  this.element = element;
37048
37091
  this._localeId = _localeId;
@@ -37051,6 +37094,7 @@ class IgxDatePickerComponent extends PickerBaseDirective {
37051
37094
  this._injector = _injector;
37052
37095
  this._renderer = _renderer;
37053
37096
  this.platform = platform;
37097
+ this.cdr = cdr;
37054
37098
  this._displayDensityOptions = _displayDensityOptions;
37055
37099
  this._inputGroupType = _inputGroupType;
37056
37100
  /**
@@ -37507,6 +37551,10 @@ class IgxDatePickerComponent extends PickerBaseDirective {
37507
37551
  if (this._ngControl) {
37508
37552
  this._statusChanges$ =
37509
37553
  this._ngControl.statusChanges.subscribe(this.onStatusChanged.bind(this));
37554
+ if (this._ngControl.control.validator) {
37555
+ this.inputGroup.isRequired = this.required;
37556
+ this.cdr.detectChanges();
37557
+ }
37510
37558
  }
37511
37559
  }
37512
37560
  /** @hidden @internal */
@@ -37715,6 +37763,7 @@ IgxDatePickerComponent.ctorParameters = () => [
37715
37763
  { type: Injector },
37716
37764
  { type: Renderer2 },
37717
37765
  { type: PlatformUtil },
37766
+ { type: ChangeDetectorRef },
37718
37767
  { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] },
37719
37768
  { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [IGX_INPUT_GROUP_TYPE,] }] }
37720
37769
  ];
@@ -39148,7 +39197,7 @@ class IgxExcelStyleClearFiltersComponent {
39148
39197
  IgxExcelStyleClearFiltersComponent.decorators = [
39149
39198
  { type: Component, args: [{
39150
39199
  selector: 'igx-excel-style-clear-filters',
39151
- template: "<div *ngIf=\"esf.column\"\n tabindex=\"0\"\n [ngClass]=\"clearFilterClass()\"\n (keydown)=\"onClearFilterKeyDown($event)\"\n (click)=\"clearFilter()\">\n <span>{{ esf.grid.resourceStrings.igx_grid_excel_filter_clear }}</span>\n <igx-icon>clear</igx-icon>\n</div>\n"
39200
+ template: "<div *ngIf=\"esf.column\"\n tabindex=\"0\"\n [ngClass]=\"clearFilterClass()\"\n (keydown)=\"onClearFilterKeyDown($event)\"\n (click)=\"clearFilter()\"\n role=\"menuitem\">\n <span>{{ esf.grid.resourceStrings.igx_grid_excel_filter_clear }}</span>\n <igx-icon>clear</igx-icon>\n</div>\n"
39152
39201
  },] }
39153
39202
  ];
39154
39203
  IgxExcelStyleClearFiltersComponent.ctorParameters = () => [
@@ -40972,7 +41021,7 @@ IgxExcelStyleConditionalFilterComponent.decorators = [
40972
41021
  { type: Component, args: [{
40973
41022
  preserveWhitespaces: false,
40974
41023
  selector: 'igx-excel-style-conditional-filter',
40975
- template: "<ng-container *ngIf=\"esf.column\">\n <div tabindex=\"0\"\n class=\"igx-excel-filter__actions-filter\"\n (keydown)=\"onTextFilterKeyDown($event)\"\n (click)=\"onTextFilterClick($event)\"\n [igxDropDownItemNavigation]=\"subMenu\">\n <span>{{ subMenuText }}</span>\n <igx-icon>keyboard_arrow_right</igx-icon>\n </div>\n\n <igx-drop-down\n #subMenu\n [maxHeight]=\"'397px'\"\n [displayDensity]=\"esf.grid.displayDensity\"\n (selectionChanging)=\"onSubMenuSelection($event)\"\n (closed)=\"onSubMenuClosed()\"\n [allowItemsFocus]=\"true\">\n <div>\n <igx-drop-down-item\n *ngFor=\"let condition of conditions\"\n [value]=\"condition\">\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon family=\"imx-icons\" [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 <igx-drop-down-item *ngIf=\"showCustomFilterItem()\">\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon>filter_list</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 </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 [overlayService]=\"esf.overlayService\"\n [displayDensity]=\"esf.grid.displayDensity\">\n </igx-excel-style-custom-dialog>\n</ng-container>\n"
41024
+ template: "<ng-container *ngIf=\"esf.column\">\n <div tabindex=\"0\"\n class=\"igx-excel-filter__actions-filter\"\n (keydown)=\"onTextFilterKeyDown($event)\"\n (click)=\"onTextFilterClick($event)\"\n [igxDropDownItemNavigation]=\"subMenu\"\n role=\"menuitem\"\n aria-haspopup=\"true\">\n <span>{{ subMenuText }}</span>\n <igx-icon>keyboard_arrow_right</igx-icon>\n </div>\n\n <igx-drop-down\n #subMenu\n [maxHeight]=\"'397px'\"\n [displayDensity]=\"esf.grid.displayDensity\"\n (selectionChanging)=\"onSubMenuSelection($event)\"\n (closed)=\"onSubMenuClosed()\"\n [allowItemsFocus]=\"true\">\n <div>\n <igx-drop-down-item\n *ngFor=\"let condition of conditions\"\n [value]=\"condition\">\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon family=\"imx-icons\" [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 <igx-drop-down-item *ngIf=\"showCustomFilterItem()\">\n <div class=\"igx-grid__filtering-dropdown-items\">\n <igx-icon>filter_list</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 </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 [overlayService]=\"esf.overlayService\"\n [displayDensity]=\"esf.grid.displayDensity\">\n </igx-excel-style-custom-dialog>\n</ng-container>\n"
40976
41025
  },] }
40977
41026
  ];
40978
41027
  IgxExcelStyleConditionalFilterComponent.ctorParameters = () => [
@@ -41020,7 +41069,7 @@ IgxExcelStyleHidingComponent.decorators = [
41020
41069
  { type: Component, args: [{
41021
41070
  preserveWhitespaces: false,
41022
41071
  selector: 'igx-excel-style-hiding',
41023
- template: "<div *ngIf=\"esf.column\"\n class=\"igx-excel-filter__actions-hide\"\n tabindex=\"0\"\n (click)=\"esf.onHideToggle()\">\n <span>{{ esf.column.hidden ? esf.grid.resourceStrings.igx_grid_excel_show : esf.grid.resourceStrings.igx_grid_excel_hide }}</span>\n <igx-icon>{{ esf.column.hidden ? 'visibility' : 'visibility_off' }}</igx-icon>\n</div>\n"
41072
+ template: "<div *ngIf=\"esf.column\"\n class=\"igx-excel-filter__actions-hide\"\n tabindex=\"0\"\n (click)=\"esf.onHideToggle()\"\n role=\"menuitem\">\n <span>{{ esf.column.hidden ? esf.grid.resourceStrings.igx_grid_excel_show : esf.grid.resourceStrings.igx_grid_excel_hide }}</span>\n <igx-icon>{{ esf.column.hidden ? 'visibility' : 'visibility_off' }}</igx-icon>\n</div>\n"
41024
41073
  },] }
41025
41074
  ];
41026
41075
  IgxExcelStyleHidingComponent.ctorParameters = () => [
@@ -41138,7 +41187,7 @@ IgxExcelStylePinningComponent.decorators = [
41138
41187
  { type: Component, args: [{
41139
41188
  preserveWhitespaces: false,
41140
41189
  selector: 'igx-excel-style-pinning',
41141
- template: "<div *ngIf=\"esf.column\"\n [ngClass]=\"esf.column.pinned ? 'igx-excel-filter__actions-unpin' : 'igx-excel-filter__actions-pin'\"\n (click)=\"esf.onPin()\"\n tabindex=\"0\">\n <span>{{ esf.column.pinned ? esf.grid.resourceStrings.igx_grid_excel_unpin : esf.grid.resourceStrings.igx_grid_excel_pin }}</span>\n <igx-icon family=\"imx-icons\" name=\"{{ esf.column.pinned ? 'unpin-left' : 'pin-left' }}\"></igx-icon>\n</div>\n"
41190
+ template: "<div *ngIf=\"esf.column\"\n [ngClass]=\"esf.column.pinned ? 'igx-excel-filter__actions-unpin' : 'igx-excel-filter__actions-pin'\"\n (click)=\"esf.onPin()\"\n tabindex=\"0\"\n role=\"menuitem\">\n <span>{{ esf.column.pinned ? esf.grid.resourceStrings.igx_grid_excel_unpin : esf.grid.resourceStrings.igx_grid_excel_pin }}</span>\n <igx-icon family=\"imx-icons\" name=\"{{ esf.column.pinned ? 'unpin-left' : 'pin-left' }}\"></igx-icon>\n</div>\n"
41142
41191
  },] }
41143
41192
  ];
41144
41193
  IgxExcelStylePinningComponent.ctorParameters = () => [
@@ -42615,7 +42664,7 @@ IgxExcelStyleSelectingComponent.decorators = [
42615
42664
  { type: Component, args: [{
42616
42665
  preserveWhitespaces: false,
42617
42666
  selector: 'igx-excel-style-selecting',
42618
- template: "<div *ngIf=\"esf.column\"\n [ngClass]=\"esf.selectedClass()\"\n tabindex=\"0\"\n (click)=\"esf.onSelect()\">\n <span>{{esf.grid.resourceStrings.igx_grid_excel_select }}</span>\n <igx-icon>done</igx-icon>\n</div>\n"
42667
+ template: "<div *ngIf=\"esf.column\"\n [ngClass]=\"esf.selectedClass()\"\n tabindex=\"0\"\n (click)=\"esf.onSelect()\"\n role=\"button\"\n [attr.aria-pressed]=\"esf.column.selected\">\n <span>{{esf.grid.resourceStrings.igx_grid_excel_select }}</span>\n <igx-icon>done</igx-icon>\n</div>\n"
42619
42668
  },] }
42620
42669
  ];
42621
42670
  IgxExcelStyleSelectingComponent.ctorParameters = () => [
@@ -46374,6 +46423,48 @@ class IgxSnackbarComponent extends IgxNotificationsDirective {
46374
46423
  * ```
46375
46424
  */
46376
46425
  this.animationDone = new EventEmitter();
46426
+ this._positionSettings = {
46427
+ horizontalDirection: HorizontalAlignment.Center,
46428
+ verticalDirection: VerticalAlignment.Bottom,
46429
+ openAnimation: useAnimation(fadeIn, { params: { duration: '.35s', easing: 'cubic-bezier(0.0, 0.0, 0.2, 1)',
46430
+ fromPosition: 'translateY(100%)', toPosition: 'translateY(0)' } }),
46431
+ closeAnimation: useAnimation(fadeOut, { params: { duration: '.2s', easing: 'cubic-bezier(0.4, 0.0, 1, 1)',
46432
+ fromPosition: 'translateY(0)', toPosition: 'translateY(100%)' } }),
46433
+ };
46434
+ }
46435
+ /**
46436
+ * Get the position and animation settings used by the snackbar.
46437
+ * ```typescript
46438
+ * @ViewChild('snackbar', { static: true }) public snackbar: IgxSnackbarComponent;
46439
+ * let currentPosition: PositionSettings = this.snackbar.positionSettings
46440
+ * ```
46441
+ */
46442
+ get positionSettings() {
46443
+ return this._positionSettings;
46444
+ }
46445
+ /**
46446
+ * Set the position and animation settings used by the snackbar.
46447
+ * ```html
46448
+ * <igx-snackbar [positionSettings]="newPositionSettings"></igx-snackbar>
46449
+ * ```
46450
+ * ```typescript
46451
+ * import { slideInTop, slideOutBottom } from 'igniteui-angular';
46452
+ * ...
46453
+ * @ViewChild('snackbar', { static: true }) public snackbar: IgxSnackbarComponent;
46454
+ * public newPositionSettings: PositionSettings = {
46455
+ * openAnimation: useAnimation(slideInTop, { params: { duration: '1000ms', fromPosition: 'translateY(100%)'}}),
46456
+ * closeAnimation: useAnimation(slideOutBottom, { params: { duration: '1000ms', fromPosition: 'translateY(0)'}}),
46457
+ * horizontalDirection: HorizontalAlignment.Left,
46458
+ * verticalDirection: VerticalAlignment.Middle,
46459
+ * horizontalStartPoint: HorizontalAlignment.Left,
46460
+ * verticalStartPoint: VerticalAlignment.Middle,
46461
+ * minSize: { height: 100, width: 100 }
46462
+ * };
46463
+ * this.snackbar.positionSettings = this.newPositionSettings;
46464
+ * ```
46465
+ */
46466
+ set positionSettings(settings) {
46467
+ this._positionSettings = settings;
46377
46468
  }
46378
46469
  /**
46379
46470
  * Shows the snackbar and hides it after the `displayTime` is over if `autoHide` is set to `true`.
@@ -46385,31 +46476,25 @@ class IgxSnackbarComponent extends IgxNotificationsDirective {
46385
46476
  if (message !== undefined) {
46386
46477
  this.textMessage = message;
46387
46478
  }
46388
- const snackbarSettings = {
46389
- horizontalDirection: HorizontalAlignment.Center,
46390
- verticalDirection: VerticalAlignment.Bottom,
46391
- openAnimation: useAnimation(slideInBottom, {
46392
- params: {
46393
- duration: '.35s',
46394
- easing: 'cubic-bezier(0.0, 0.0, 0.2, 1)',
46395
- fromPosition: 'translateY(100%)',
46396
- toPosition: 'translateY(0)'
46397
- }
46398
- }),
46399
- closeAnimation: useAnimation(slideOutBottom, {
46400
- params: {
46401
- duration: '.2s',
46402
- easing: 'cubic-bezier(0.4, 0.0, 1, 1)',
46403
- fromPosition: 'translateY(0)',
46404
- toOpacity: 1,
46405
- toPosition: 'translateY(100%)'
46406
- }
46407
- })
46408
- };
46409
- this.strategy = this.outlet ? new ContainerPositionStrategy(snackbarSettings)
46410
- : new GlobalPositionStrategy(snackbarSettings);
46479
+ this.strategy = this.outlet ? new ContainerPositionStrategy(this.positionSettings)
46480
+ : new GlobalPositionStrategy(this.positionSettings);
46411
46481
  super.open();
46412
46482
  }
46483
+ /**
46484
+ * Opens or closes the snackbar, depending on its current state.
46485
+ *
46486
+ * ```typescript
46487
+ * this.snackbar.toggle();
46488
+ * ```
46489
+ */
46490
+ toggle() {
46491
+ if (this.collapsed || this.isClosing) {
46492
+ this.open();
46493
+ }
46494
+ else {
46495
+ this.close();
46496
+ }
46497
+ }
46413
46498
  /**
46414
46499
  * @hidden
46415
46500
  */
@@ -46442,7 +46527,8 @@ IgxSnackbarComponent.propDecorators = {
46442
46527
  actionText: [{ type: Input }],
46443
46528
  clicked: [{ type: Output }],
46444
46529
  animationStarted: [{ type: Output }],
46445
- animationDone: [{ type: Output }]
46530
+ animationDone: [{ type: Output }],
46531
+ positionSettings: [{ type: Input }]
46446
46532
  };
46447
46533
  /**
46448
46534
  * @hidden
@@ -46871,7 +46957,7 @@ class IgxGridFilteringRowComponent {
46871
46957
  .subscribe(() => {
46872
46958
  this.cdr.markForCheck();
46873
46959
  });
46874
- this.focusEditElement();
46960
+ requestAnimationFrame(() => this.focusEditElement());
46875
46961
  }
46876
46962
  get disabled() {
46877
46963
  return !(this.column.filteringExpressionsTree && this.column.filteringExpressionsTree.filteringOperands.length > 0);
@@ -49183,6 +49269,7 @@ class IgxGridBaseDirective extends DisplayDensityBase {
49183
49269
  positionStrategy: this.rowEditPositioningStrategy
49184
49270
  };
49185
49271
  this.transactionChange$ = new Subject();
49272
+ this._rendered = false;
49186
49273
  this.DRAG_SCROLL_DELTA = 10;
49187
49274
  /**
49188
49275
  * @hidden @internal
@@ -50985,6 +51072,7 @@ class IgxGridBaseDirective extends DisplayDensityBase {
50985
51072
  this.paginator.totalRecords = this.totalRecords;
50986
51073
  this.paginator.overlaySettings = { outlet: this.outlet };
50987
51074
  }
51075
+ this._rendered = true;
50988
51076
  });
50989
51077
  Promise.resolve().then(() => this.rendered.next(true));
50990
51078
  }
@@ -51303,16 +51391,23 @@ class IgxGridBaseDirective extends DisplayDensityBase {
51303
51391
  get summariesMargin() {
51304
51392
  return this.featureColumnsWidth();
51305
51393
  }
51394
+ /**
51395
+ * @hidden
51396
+ * @internal
51397
+ */
51398
+ get columns() {
51399
+ return this._columns;
51400
+ }
51306
51401
  /**
51307
51402
  * Gets an array of `IgxColumnComponent`s.
51308
51403
  *
51309
51404
  * @example
51310
51405
  * ```typescript
51311
- * const colums = this.grid.columns.
51406
+ * const colums = this.grid.columnsCollection.
51312
51407
  * ```
51313
51408
  */
51314
- get columns() {
51315
- return this._columns;
51409
+ get columnsCollection() {
51410
+ return this._rendered ? this._columns : [];
51316
51411
  }
51317
51412
  /**
51318
51413
  * Gets an array of the pinned `IgxColumnComponent`s.
@@ -53055,6 +53150,92 @@ class IgxGridBaseDirective extends DisplayDensityBase {
53055
53150
  endEdit(commit = true, event) {
53056
53151
  this.crudService.endEdit(commit, event);
53057
53152
  }
53153
+ /**
53154
+ * Enters add mode by spawning the UI under the specified row by rowID.
53155
+ *
53156
+ * @remarks
53157
+ * If null is passed as rowID, the row adding UI is spawned as the first record in the data view
53158
+ * @remarks
53159
+ * Spawning the UI to add a child for a record only works if you provide a rowID
53160
+ * @example
53161
+ * ```typescript
53162
+ * this.grid.beginAddRowById('ALFKI');
53163
+ * this.grid.beginAddRowById('ALFKI', true);
53164
+ * this.grid.beginAddRowById(null);
53165
+ * ```
53166
+ * @param rowID - The rowID to spawn the add row UI for, or null to spawn it as the first record in the data view
53167
+ * @param asChild - Whether the record should be added as a child. Only applicable to igxTreeGrid.
53168
+ */
53169
+ beginAddRowById(rowID, asChild) {
53170
+ let index = rowID;
53171
+ if (rowID == null) {
53172
+ if (asChild) {
53173
+ console.warn('The record cannot be added as a child to an unspecified record.');
53174
+ return;
53175
+ }
53176
+ index = 0;
53177
+ }
53178
+ else {
53179
+ // find the index of the record with that PK
53180
+ index = this.gridAPI.get_rec_index_by_id(rowID, this.dataView);
53181
+ rowID = index;
53182
+ if (index === -1) {
53183
+ console.warn('No row with the specified ID was found.');
53184
+ return;
53185
+ }
53186
+ }
53187
+ if (!this.dataView.length) {
53188
+ this.beginAddRowForIndex(rowID, asChild);
53189
+ return;
53190
+ }
53191
+ // check if the index is valid - won't support anything outside the data view
53192
+ if (index >= 0 && index < this.dataView.length) {
53193
+ // check if the index is in the view port
53194
+ if ((index < this.virtualizationState.startIndex ||
53195
+ index >= this.virtualizationState.startIndex + this.virtualizationState.chunkSize) &&
53196
+ !this.isRecordPinnedByViewIndex(index)) {
53197
+ this.verticalScrollContainer.chunkLoad
53198
+ .pipe(first$1(), takeUntil(this.destroy$))
53199
+ .subscribe(() => {
53200
+ this.beginAddRowForIndex(rowID, asChild);
53201
+ });
53202
+ this.navigateTo(index);
53203
+ this.notifyChanges(true);
53204
+ return;
53205
+ }
53206
+ this.beginAddRowForIndex(rowID, asChild);
53207
+ }
53208
+ else {
53209
+ console.warn('The row with the specified PK or index is outside of the current data view.');
53210
+ }
53211
+ }
53212
+ /**
53213
+ * Enters add mode by spawning the UI at the specified index.
53214
+ *
53215
+ * @remarks
53216
+ * Accepted values for index are integers from 0 to this.grid.dataView.length
53217
+ * @example
53218
+ * ```typescript
53219
+ * this.grid.beginAddRowByIndex(0);
53220
+ * ```
53221
+ * @param index - The index to spawn the UI at. Accepts integers from 0 to this.grid.dataView.length
53222
+ */
53223
+ beginAddRowByIndex(index) {
53224
+ if (index === 0) {
53225
+ return this.beginAddRowById(null);
53226
+ }
53227
+ return this.beginAddRowById(this.gridAPI.get_rec_id_by_index(index - 1, this.dataView));
53228
+ }
53229
+ beginAddRowForIndex(index, asChild = false) {
53230
+ const row = index == null ?
53231
+ null : this.rowList.find(r => r.index === index);
53232
+ if (row !== undefined) {
53233
+ this.crudService.enterAddRowMode(row, asChild);
53234
+ }
53235
+ else {
53236
+ console.warn('No row with the specified PK or index was found.');
53237
+ }
53238
+ }
53058
53239
  switchTransactionService(val) {
53059
53240
  if (val) {
53060
53241
  this._transactions = this.transactionFactory.create("Base" /* Base */);
@@ -60272,7 +60453,8 @@ class IgxGridGroupByRowComponent {
60272
60453
  * @hidden @internal
60273
60454
  */
60274
60455
  get selectedRowsInTheGroup() {
60275
- return this.groupRow.records.filter(rowID => this.gridSelection.filteredSelectedRowIds.indexOf(this.getRowID(rowID)) > -1);
60456
+ const selectedIds = this.gridSelection.filteredSelectedRowIds;
60457
+ return this.groupRow.records.filter(rowID => selectedIds.indexOf(this.getRowID(rowID)) > -1);
60276
60458
  }
60277
60459
  /**
60278
60460
  * @hidden @internal
@@ -61134,6 +61316,7 @@ class IgxGridComponent extends IgxGridBaseDirective {
61134
61316
  */
61135
61317
  clearGrouping(name) {
61136
61318
  this._gridAPI.clear_groupby(name);
61319
+ this.calculateGridSizes();
61137
61320
  this.notifyChanges(true);
61138
61321
  }
61139
61322
  preventHeaderScroll(args) {
@@ -63755,6 +63938,30 @@ class IgxTreeGridAPIService extends GridBaseAPIService {
63755
63938
  get_rec_by_id(rowID) {
63756
63939
  return this.grid.records.get(rowID);
63757
63940
  }
63941
+ /**
63942
+ * Gets the rowID of the record at the specified data view index
63943
+ *
63944
+ * @param index
63945
+ * @param dataCollection
63946
+ */
63947
+ get_rec_id_by_index(index, dataCollection) {
63948
+ dataCollection = dataCollection || this.grid.data;
63949
+ if (index >= 0 && index < dataCollection.length) {
63950
+ const rec = dataCollection[index];
63951
+ return this.grid.primaryKey ? rec.data[this.grid.primaryKey] : rec.data;
63952
+ }
63953
+ return null;
63954
+ }
63955
+ /**
63956
+ * Returns the index of the record in the data view by pk or -1 if not found or primaryKey is not set.
63957
+ *
63958
+ * @param pk
63959
+ * @param dataCollection
63960
+ */
63961
+ get_rec_index_by_id(pk, dataCollection) {
63962
+ dataCollection = dataCollection || this.grid.data;
63963
+ return this.grid.primaryKey ? dataCollection.findIndex(rec => rec.data[this.grid.primaryKey] === pk) : -1;
63964
+ }
63758
63965
  addRowToData(data, parentRowID) {
63759
63966
  if (parentRowID !== undefined && parentRowID !== null) {
63760
63967
  const state = this.grid.transactions.getState(parentRowID);
@@ -64635,6 +64842,31 @@ class IgxTreeGridComponent extends IgxGridBaseDirective {
64635
64842
  this.pipeTrigger++;
64636
64843
  this.notifyChanges();
64637
64844
  }
64845
+ /**
64846
+ * Enters add mode by spawning the UI with the context of the specified row by index.
64847
+ *
64848
+ * @remarks
64849
+ * Accepted values for index are integers from 0 to this.grid.dataView.length
64850
+ * @remarks
64851
+ * When adding the row as a child, the parent row is the specified row.
64852
+ * @remarks
64853
+ * To spawn the UI on top, call the function with index = null or a negative number.
64854
+ * In this case trying to add this row as a child will result in error.
64855
+ * @example
64856
+ * ```typescript
64857
+ * this.grid.beginAddRowByIndex(10);
64858
+ * this.grid.beginAddRowByIndex(10, true);
64859
+ * this.grid.beginAddRowByIndex(null);
64860
+ * ```
64861
+ * @param index - The index to spawn the UI at. Accepts integers from 0 to this.grid.dataView.length
64862
+ * @param asChild - Whether the record should be added as a child. Only applicable to igxTreeGrid.
64863
+ */
64864
+ beginAddRowByIndex(index, asChild) {
64865
+ if (index === null || index < 0) {
64866
+ return this.beginAddRowById(null, asChild);
64867
+ }
64868
+ return this.beginAddRowById(this.gridAPI.get_rec_id_by_index(index, this.dataView), asChild);
64869
+ }
64638
64870
  /**
64639
64871
  * @hidden
64640
64872
  */
@@ -71479,8 +71711,6 @@ class IgxTabsDirective extends IgxCarouselComponentBase {
71479
71711
  /** @hidden */
71480
71712
  constructor(builder) {
71481
71713
  super(builder);
71482
- /** @hidden */
71483
- this.role = 'tabs';
71484
71714
  /**
71485
71715
  * Output to enable support for two-way binding on [(selectedIndex)]
71486
71716
  */
@@ -71707,7 +71937,6 @@ IgxTabsDirective.ctorParameters = () => [
71707
71937
  { type: AnimationBuilder }
71708
71938
  ];
71709
71939
  IgxTabsDirective.propDecorators = {
71710
- role: [{ type: HostBinding, args: ['attr.role',] }],
71711
71940
  selectedIndex: [{ type: Input }],
71712
71941
  disableAnimation: [{ type: Input }],
71713
71942
  selectedIndexChange: [{ type: Output }],
@@ -72397,6 +72626,49 @@ class IgxToastComponent extends IgxNotificationsDirective {
72397
72626
  * @memberof IgxToastComponent
72398
72627
  */
72399
72628
  this.position = 'bottom';
72629
+ this._positionSettings = {
72630
+ horizontalDirection: HorizontalAlignment.Center,
72631
+ verticalDirection: this.position === 'bottom'
72632
+ ? VerticalAlignment.Bottom
72633
+ : this.position === 'middle'
72634
+ ? VerticalAlignment.Middle
72635
+ : VerticalAlignment.Top,
72636
+ openAnimation: useAnimation(fadeIn),
72637
+ closeAnimation: useAnimation(fadeOut),
72638
+ };
72639
+ }
72640
+ /**
72641
+ * Get the position and animation settings used by the toast.
72642
+ * ```typescript
72643
+ * @ViewChild('toast', { static: true }) public toast: IgxToastComponent;
72644
+ * let currentPosition: PositionSettings = this.toast.positionSettings
72645
+ * ```
72646
+ */
72647
+ get positionSettings() {
72648
+ return this._positionSettings;
72649
+ }
72650
+ /**
72651
+ * Set the position and animation settings used by the toast.
72652
+ * ```html
72653
+ * <igx-toast [positionSettings]="newPositionSettings"></igx-toast>
72654
+ * ```
72655
+ * ```typescript
72656
+ * import { slideInTop, slideOutBottom } from 'igniteui-angular';
72657
+ * ...
72658
+ * @ViewChild('toast', { static: true }) public toast: IgxToastComponent;
72659
+ * public newPositionSettings: PositionSettings = {
72660
+ * openAnimation: useAnimation(slideInTop, { params: { duration: '1000ms', fromPosition: 'translateY(100%)'}}),
72661
+ * closeAnimation: useAnimation(slideOutBottom, { params: { duration: '1000ms', fromPosition: 'translateY(0)'}}),
72662
+ * horizontalDirection: HorizontalAlignment.Left,
72663
+ * verticalDirection: VerticalAlignment.Middle,
72664
+ * horizontalStartPoint: HorizontalAlignment.Left,
72665
+ * verticalStartPoint: VerticalAlignment.Middle
72666
+ * };
72667
+ * this.toast.positionSettings = this.newPositionSettings;
72668
+ * ```
72669
+ */
72670
+ set positionSettings(settings) {
72671
+ this._positionSettings = settings;
72400
72672
  }
72401
72673
  /**
72402
72674
  * Gets the nativeElement of the toast.
@@ -72421,17 +72693,24 @@ class IgxToastComponent extends IgxNotificationsDirective {
72421
72693
  if (message !== undefined) {
72422
72694
  this.textMessage = message;
72423
72695
  }
72424
- const toastSettings = {
72425
- horizontalDirection: HorizontalAlignment.Center,
72426
- verticalDirection: this.position === 'bottom'
72427
- ? VerticalAlignment.Bottom
72428
- : this.position === 'middle'
72429
- ? VerticalAlignment.Middle
72430
- : VerticalAlignment.Top
72431
- };
72432
- this.strategy = new GlobalPositionStrategy(toastSettings);
72696
+ this.strategy = new GlobalPositionStrategy(this.positionSettings);
72433
72697
  super.open();
72434
72698
  }
72699
+ /**
72700
+ * Opens or closes the toast, depending on its current state.
72701
+ *
72702
+ * ```typescript
72703
+ * this.toast.toggle();
72704
+ * ```
72705
+ */
72706
+ toggle() {
72707
+ if (this.collapsed || this.isClosing) {
72708
+ this.open();
72709
+ }
72710
+ else {
72711
+ this.close();
72712
+ }
72713
+ }
72435
72714
  /**
72436
72715
  * @hidden
72437
72716
  */
@@ -72463,7 +72742,8 @@ IgxToastComponent.propDecorators = {
72463
72742
  id: [{ type: HostBinding, args: ['attr.id',] }, { type: Input }],
72464
72743
  role: [{ type: HostBinding, args: ['attr.role',] }, { type: Input }],
72465
72744
  isVisibleChange: [{ type: Output }],
72466
- position: [{ type: Input }]
72745
+ position: [{ type: Input }],
72746
+ positionSettings: [{ type: Input }]
72467
72747
  };
72468
72748
  /**
72469
72749
  * @hidden