@clr/angular 16.5.0 → 16.5.1

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 (31) hide show
  1. package/clarity.api.md +13 -5
  2. package/data/datagrid/datagrid-detail-header.d.ts +4 -1
  3. package/data/datagrid/datagrid-filter.d.ts +4 -2
  4. package/data/datagrid/datagrid-virtual-scroll.directive.d.ts +5 -2
  5. package/data/datagrid/datagrid.d.ts +1 -0
  6. package/data/datagrid/enums/column-changes.enum.d.ts +2 -1
  7. package/data/datagrid/providers/columns.service.d.ts +1 -0
  8. package/data/datagrid/providers/detail.service.d.ts +3 -0
  9. package/data/datagrid/render/main-renderer.d.ts +1 -1
  10. package/data/datagrid/utils/key-navigation-grid.controller.d.ts +1 -0
  11. package/esm2020/data/datagrid/datagrid-action-overflow.mjs +3 -1
  12. package/esm2020/data/datagrid/datagrid-detail-header.mjs +12 -6
  13. package/esm2020/data/datagrid/datagrid-detail.mjs +3 -3
  14. package/esm2020/data/datagrid/datagrid-filter.mjs +19 -12
  15. package/esm2020/data/datagrid/datagrid-row.mjs +3 -3
  16. package/esm2020/data/datagrid/datagrid-virtual-scroll.directive.mjs +13 -5
  17. package/esm2020/data/datagrid/datagrid.mjs +17 -6
  18. package/esm2020/data/datagrid/enums/column-changes.enum.mjs +3 -2
  19. package/esm2020/data/datagrid/providers/columns.service.mjs +9 -3
  20. package/esm2020/data/datagrid/providers/detail.service.mjs +9 -2
  21. package/esm2020/data/datagrid/render/cell-renderer.mjs +1 -3
  22. package/esm2020/data/datagrid/render/main-renderer.mjs +21 -16
  23. package/esm2020/data/datagrid/utils/key-navigation-grid.controller.mjs +6 -3
  24. package/esm2020/forms/common/abstract-container.mjs +5 -2
  25. package/esm2020/timeline/timeline-step.mjs +3 -3
  26. package/esm2020/timeline/timeline.mjs +3 -3
  27. package/fesm2015/clr-angular.mjs +287 -231
  28. package/fesm2015/clr-angular.mjs.map +1 -1
  29. package/fesm2020/clr-angular.mjs +282 -226
  30. package/fesm2020/clr-angular.mjs.map +1 -1
  31. package/package.json +2 -2
@@ -4751,7 +4751,10 @@ class ClrAbstractContainer {
4751
4751
  this.subscriptions = [];
4752
4752
  this.subscriptions.push(this.ifControlStateService.statusChanges.subscribe((state) => {
4753
4753
  this.state = state;
4754
- this.updateHelpers();
4754
+ // Make sure everything is updated before dispatching the values for helpers
4755
+ setTimeout(() => {
4756
+ this.updateHelpers();
4757
+ });
4755
4758
  }));
4756
4759
  this.subscriptions.push(this.ngControlService.controlChanges.subscribe(control => {
4757
4760
  this.control = control;
@@ -12058,6 +12061,191 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
12058
12061
  type: Directive
12059
12062
  }], ctorParameters: function () { return [{ type: FiltersProvider }]; } });
12060
12063
 
12064
+ /*
12065
+ * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
12066
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
12067
+ * This software is released under MIT license.
12068
+ * The full license information can be found in LICENSE in the root directory of this project.
12069
+ */
12070
+ function getTabableItems(el) {
12071
+ const tabableSelector = [
12072
+ 'a[href]',
12073
+ 'area[href]',
12074
+ 'input:not([disabled])',
12075
+ 'button:not([disabled])',
12076
+ 'select:not([disabled])',
12077
+ 'textarea:not([disabled])',
12078
+ 'iframe',
12079
+ 'object',
12080
+ 'embed',
12081
+ '*[tabindex]',
12082
+ '*[contenteditable=true]',
12083
+ '[role=button]:not([disabled])',
12084
+ ].join(',');
12085
+ return Array.from(el.querySelectorAll(tabableSelector));
12086
+ }
12087
+ class KeyNavigationGridController {
12088
+ constructor(zone) {
12089
+ this.zone = zone;
12090
+ this.skipItemFocus = false;
12091
+ this.listenersAdded = false;
12092
+ this.destroy$ = new Subject();
12093
+ this._activeCell = null;
12094
+ this.config = {
12095
+ keyGridRows: '[role=row]:not(.datagrid-placeholder)',
12096
+ keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
12097
+ keyGrid: '[role=grid]',
12098
+ };
12099
+ }
12100
+ get grid() {
12101
+ return this.host?.querySelector(this.config.keyGrid);
12102
+ }
12103
+ get rows() {
12104
+ return this.host?.querySelectorAll(this.config.keyGridRows);
12105
+ }
12106
+ get cells() {
12107
+ return this.host?.querySelectorAll(this.config.keyGridCells);
12108
+ }
12109
+ ngOnDestroy() {
12110
+ this.destroy$.next();
12111
+ this.destroy$.complete();
12112
+ }
12113
+ addListeners() {
12114
+ if (this.listenersAdded) {
12115
+ return;
12116
+ }
12117
+ this.zone.runOutsideAngular(() => {
12118
+ fromEvent(this.grid, 'mousedown')
12119
+ .pipe(takeUntil(this.destroy$))
12120
+ .subscribe((e) => {
12121
+ // preserve right click for context menus & keyboard mouse control https://apple.stackexchange.com/questions/32715/how-do-i-open-the-context-menu-from-a-mac-keyboard
12122
+ if (e.buttons === 1 && !e.ctrlKey) {
12123
+ const activeCell = this.cells
12124
+ ? Array.from(this.cells).find(c => c === e.target || c === e.target.closest(this.config.keyGridCells))
12125
+ : null;
12126
+ if (activeCell) {
12127
+ this.setActiveCell(activeCell);
12128
+ }
12129
+ }
12130
+ });
12131
+ fromEvent(this.grid, 'wheel')
12132
+ .pipe(takeUntil(this.destroy$))
12133
+ .subscribe(() => {
12134
+ this.removeActiveCell();
12135
+ });
12136
+ fromEvent(this.grid, 'keydown')
12137
+ .pipe(takeUntil(this.destroy$))
12138
+ .subscribe((e) => {
12139
+ // Skip column resize events
12140
+ if (e.target.classList.contains('drag-handle') &&
12141
+ (e.code === 'ArrowLeft' || e.code === 'ArrowRight')) {
12142
+ return;
12143
+ }
12144
+ if (e.code === 'ArrowUp' ||
12145
+ e.code === 'ArrowDown' ||
12146
+ e.code === 'ArrowLeft' ||
12147
+ e.code === 'ArrowRight' ||
12148
+ e.code === 'End' ||
12149
+ e.code === 'Home' ||
12150
+ e.code === 'PageUp' ||
12151
+ e.code === 'PageDown') {
12152
+ const { x, y } = this.getNextItemCoordinate(e);
12153
+ const activeItem = this.rows
12154
+ ? Array.from(this.rows[y].querySelectorAll(this.config.keyGridCells))[x]
12155
+ : null;
12156
+ if (activeItem) {
12157
+ this.setActiveCell(activeItem);
12158
+ }
12159
+ e.preventDefault();
12160
+ }
12161
+ });
12162
+ });
12163
+ this.listenersAdded = true;
12164
+ }
12165
+ initializeKeyGrid(host) {
12166
+ this.host = host;
12167
+ this.addListeners();
12168
+ this.resetKeyGrid();
12169
+ }
12170
+ resetKeyGrid() {
12171
+ this.cells?.forEach((i) => i.setAttribute('tabindex', '-1'));
12172
+ const firstCell = this.cells ? this.cells[0] : null;
12173
+ firstCell?.setAttribute('tabindex', '0');
12174
+ }
12175
+ removeActiveCell() {
12176
+ this._activeCell = null;
12177
+ }
12178
+ getActiveCell() {
12179
+ return this._activeCell;
12180
+ }
12181
+ setActiveCell(activeCell) {
12182
+ const prior = this.cells ? Array.from(this.cells).find(c => c.getAttribute('tabindex') === '0') : null;
12183
+ if (prior) {
12184
+ prior.setAttribute('tabindex', '-1');
12185
+ }
12186
+ activeCell.setAttribute('tabindex', '0');
12187
+ this._activeCell = activeCell;
12188
+ const items = getTabableItems(activeCell);
12189
+ const item = activeCell.getAttribute('role') !== 'columnheader' && items[0] ? items[0] : activeCell;
12190
+ if (!this.skipItemFocus) {
12191
+ item.focus();
12192
+ }
12193
+ }
12194
+ getNextItemCoordinate(e) {
12195
+ let currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
12196
+ if (e.code === 'Tab') {
12197
+ currentCell = document.activeElement;
12198
+ }
12199
+ const currentRow = this.rows && currentCell ? Array.from(this.rows).find(r => r.contains(currentCell)) : null;
12200
+ const numOfRows = this.rows ? this.rows.length - 1 : 0;
12201
+ const numOfColumns = this.cells ? Math.floor(this.cells.length / this.rows.length - 1) : 0;
12202
+ let x = currentRow && currentCell
12203
+ ? Array.from(currentRow.querySelectorAll(this.config.keyGridCells)).indexOf(currentCell)
12204
+ : 0;
12205
+ let y = currentRow && currentCell && this.rows ? Array.from(this.rows).indexOf(currentRow) : 0;
12206
+ const dir = this.host.dir;
12207
+ const inlineStart = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
12208
+ const inlineEnd = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
12209
+ const itemsPerPage = Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.rows[0].clientHeight) - 1 || 0;
12210
+ if (e.code === 'ArrowUp' && y !== 0) {
12211
+ y = y - 1;
12212
+ }
12213
+ else if (e.code === 'ArrowDown' && y < numOfRows) {
12214
+ y = y + 1;
12215
+ }
12216
+ else if (e.code === inlineStart && x !== 0) {
12217
+ x = x - 1;
12218
+ }
12219
+ else if (e.code === inlineEnd && x < numOfColumns) {
12220
+ x = x + 1;
12221
+ }
12222
+ else if (e.code === 'End') {
12223
+ x = numOfColumns;
12224
+ if (e.ctrlKey) {
12225
+ y = numOfRows;
12226
+ }
12227
+ }
12228
+ else if (e.code === 'Home') {
12229
+ x = 0;
12230
+ if (e.ctrlKey) {
12231
+ y = 0;
12232
+ }
12233
+ }
12234
+ else if (e.code === 'PageUp') {
12235
+ y = y - itemsPerPage > 0 ? y - itemsPerPage + 1 : 1;
12236
+ }
12237
+ else if (e.code === 'PageDown') {
12238
+ y = y + itemsPerPage < numOfRows ? y + itemsPerPage : numOfRows;
12239
+ }
12240
+ return { x, y };
12241
+ }
12242
+ }
12243
+ KeyNavigationGridController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
12244
+ KeyNavigationGridController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController });
12245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, decorators: [{
12246
+ type: Injectable
12247
+ }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
12248
+
12061
12249
  /*
12062
12250
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
12063
12251
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -12070,12 +12258,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
12070
12258
  * since it can be anything (not just a text input).
12071
12259
  */
12072
12260
  class ClrDatagridFilter extends DatagridFilterRegistrar {
12073
- constructor(_filters, commonStrings, smartToggleService, platformId, elementRef) {
12261
+ constructor(_filters, commonStrings, smartToggleService, platformId, elementRef, keyNavigation) {
12074
12262
  super(_filters);
12075
12263
  this.commonStrings = commonStrings;
12076
12264
  this.smartToggleService = smartToggleService;
12077
12265
  this.platformId = platformId;
12078
12266
  this.elementRef = elementRef;
12267
+ this.keyNavigation = keyNavigation;
12079
12268
  this.openChange = new EventEmitter(false);
12080
12269
  this.ariaExpanded = false;
12081
12270
  this.popoverId = uniqueIdFactory();
@@ -12104,6 +12293,9 @@ class ClrDatagridFilter extends DatagridFilterRegistrar {
12104
12293
  if (!open && isPlatformBrowser(this.platformId)) {
12105
12294
  this.anchor.nativeElement.focus();
12106
12295
  }
12296
+ if (this.keyNavigation) {
12297
+ this.keyNavigation.skipItemFocus = open;
12298
+ }
12107
12299
  // keep track of the state
12108
12300
  this._open = open;
12109
12301
  }
@@ -12137,7 +12329,7 @@ class ClrDatagridFilter extends DatagridFilterRegistrar {
12137
12329
  });
12138
12330
  }
12139
12331
  }
12140
- ClrDatagridFilter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridFilter, deps: [{ token: FiltersProvider }, { token: ClrCommonStringsService }, { token: ClrPopoverToggleService }, { token: PLATFORM_ID }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
12332
+ ClrDatagridFilter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridFilter, deps: [{ token: FiltersProvider }, { token: ClrCommonStringsService }, { token: ClrPopoverToggleService }, { token: PLATFORM_ID }, { token: i0.ElementRef }, { token: KeyNavigationGridController, optional: true }], target: i0.ɵɵFactoryTarget.Component });
12141
12333
  ClrDatagridFilter.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridFilter, selector: "clr-dg-filter", inputs: { open: ["clrDgFilterOpen", "open"], customFilter: ["clrDgFilter", "customFilter"] }, outputs: { openChange: "clrDgFilterOpenChange" }, providers: [{ provide: CustomFilter, useExisting: ClrDatagridFilter }], viewQueries: [{ propertyName: "anchor", first: true, predicate: ["anchor"], descendants: true, read: ElementRef }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
12142
12334
  <button
12143
12335
  class="datagrid-filter-toggle"
@@ -12222,7 +12414,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
12222
12414
  }], ctorParameters: function () { return [{ type: FiltersProvider }, { type: ClrCommonStringsService }, { type: ClrPopoverToggleService }, { type: undefined, decorators: [{
12223
12415
  type: Inject,
12224
12416
  args: [PLATFORM_ID]
12225
- }] }, { type: i0.ElementRef }]; }, propDecorators: { openChange: [{
12417
+ }] }, { type: i0.ElementRef }, { type: KeyNavigationGridController, decorators: [{
12418
+ type: Optional
12419
+ }] }]; }, propDecorators: { openChange: [{
12226
12420
  type: Output,
12227
12421
  args: ['clrDgFilterOpenChange']
12228
12422
  }], anchor: [{
@@ -12980,6 +13174,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
12980
13174
  class DetailService {
12981
13175
  constructor(modalStackService) {
12982
13176
  this.modalStackService = modalStackService;
13177
+ this.preventScroll = false;
12983
13178
  this.toggleState = false;
12984
13179
  this._enabled = false;
12985
13180
  this._state = new BehaviorSubject(this.toggleState);
@@ -12990,6 +13185,12 @@ class DetailService {
12990
13185
  set enabled(state) {
12991
13186
  this._enabled = state;
12992
13187
  }
13188
+ get preventFocusScroll() {
13189
+ return this.preventScroll;
13190
+ }
13191
+ set preventFocusScroll(preventScroll) {
13192
+ this.preventScroll = preventScroll;
13193
+ }
12993
13194
  get state() {
12994
13195
  return this.cache;
12995
13196
  }
@@ -13016,7 +13217,7 @@ class DetailService {
13016
13217
  }
13017
13218
  returnFocus() {
13018
13219
  if (this.button) {
13019
- this.button.focus();
13220
+ this.button.focus({ preventScroll: this.preventFocusScroll });
13020
13221
  this.button = null;
13021
13222
  }
13022
13223
  }
@@ -15333,7 +15534,7 @@ ClrDatagridRow.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version
15333
15534
  DatagridIfExpandService,
15334
15535
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
15335
15536
  { provide: LoadingListener, useExisting: DatagridIfExpandService },
15336
- ], queries: [{ propertyName: "dgCells", predicate: ClrDatagridCell }], viewQueries: [{ propertyName: "expandAnimation", first: true, predicate: ClrExpandableAnimation, descendants: true }, { propertyName: "detailButton", first: true, predicate: ["detailButton"], descendants: true }, { propertyName: "_stickyCells", first: true, predicate: ["stickyCells"], descendants: true, read: ViewContainerRef }, { propertyName: "_scrollableCells", first: true, predicate: ["scrollableCells"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculatedCells", first: true, predicate: ["calculatedCells"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n We need to wrap the #rowContent in label element if we are in rowSelectionMode.\n Clicking of that wrapper label will equate to clicking on the whole row, which triggers the checkbox to toggle.\n-->\n<div\n class=\"datagrid-row-clickable\"\n *ngIf=\"selection.rowSelectionMode\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n>\n <clr-expandable-animation [clrExpandTrigger]=\"expandAnimationTrigger\" *ngIf=\"expand.expandable\">\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n </clr-expandable-animation>\n <ng-template [ngTemplateOutlet]=\"rowContent\" *ngIf=\"!expand.expandable\"></ng-template>\n</div>\n\n<clr-expandable-animation\n *ngIf=\"!selection.rowSelectionMode && expand.expandable\"\n [clrExpandTrigger]=\"expandAnimationTrigger\"\n>\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n</clr-expandable-animation>\n\n<ng-template *ngIf=\"!selection.rowSelectionMode && !expand.expandable\" [ngTemplateOutlet]=\"rowContent\"></ng-template>\n\n<!--\n We need the \"project into template\" hacks because we need this in 2 different places\n depending on whether the details replace the row or not.\n-->\n<ng-template #detail>\n <ng-content select=\"clr-dg-row-detail\"></ng-content>\n</ng-template>\n\n<ng-template #rowContent>\n <div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [class.datagrid-row-detail-open]=\"detailService.isRowOpen(item)\"\n >\n <div class=\"datagrid-row-sticky\">\n <!-- Sticky elements here -->\n <ng-container #stickyCells>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-checkbox-wrapper>\n <input\n type=\"checkbox\"\n clrCheckbox\n [ngModel]=\"selected\"\n (ngModelChange)=\"toggle($event)\"\n [id]=\"checkboxId\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"checkboxId\" class=\"clr-control-label clr-col-null\" (click)=\"clearRanges($event)\">\n <span class=\"clr-sr-only\">{{clrDgRowSelectionLabel || commonStrings.keys.select}}</span>\n </label>\n </clr-checkbox-wrapper>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["for"] }, { kind: "directive", type: ClrCheckbox, selector: "[clrCheckbox],[clrToggle]" }, { kind: "component", type: ClrCheckboxWrapper, selector: "clr-checkbox-wrapper,clr-toggle-wrapper" }, { kind: "directive", type: ClrRadio, selector: "[clrRadio]" }, { kind: "component", type: ClrRadioWrapper, selector: "clr-radio-wrapper" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrExpandableAnimation, selector: "clr-expandable-animation", inputs: ["clrExpandTrigger"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }] });
15537
+ ], queries: [{ propertyName: "dgCells", predicate: ClrDatagridCell }], viewQueries: [{ propertyName: "expandAnimation", first: true, predicate: ClrExpandableAnimation, descendants: true }, { propertyName: "detailButton", first: true, predicate: ["detailButton"], descendants: true }, { propertyName: "_stickyCells", first: true, predicate: ["stickyCells"], descendants: true, read: ViewContainerRef }, { propertyName: "_scrollableCells", first: true, predicate: ["scrollableCells"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculatedCells", first: true, predicate: ["calculatedCells"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n We need to wrap the #rowContent in label element if we are in rowSelectionMode.\n Clicking of that wrapper label will equate to clicking on the whole row, which triggers the checkbox to toggle.\n-->\n<div\n class=\"datagrid-row-clickable\"\n *ngIf=\"selection.rowSelectionMode\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n>\n <clr-expandable-animation [clrExpandTrigger]=\"expandAnimationTrigger\" *ngIf=\"expand.expandable\">\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n </clr-expandable-animation>\n <ng-template [ngTemplateOutlet]=\"rowContent\" *ngIf=\"!expand.expandable\"></ng-template>\n</div>\n\n<clr-expandable-animation\n *ngIf=\"!selection.rowSelectionMode && expand.expandable\"\n [clrExpandTrigger]=\"expandAnimationTrigger\"\n>\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n</clr-expandable-animation>\n\n<ng-template *ngIf=\"!selection.rowSelectionMode && !expand.expandable\" [ngTemplateOutlet]=\"rowContent\"></ng-template>\n\n<!--\n We need the \"project into template\" hacks because we need this in 2 different places\n depending on whether the details replace the row or not.\n-->\n<ng-template #detail>\n <ng-content select=\"clr-dg-row-detail\"></ng-content>\n</ng-template>\n\n<ng-template #rowContent>\n <div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [class.datagrid-row-detail-open]=\"detailService.isRowOpen(item)\"\n >\n <div class=\"datagrid-row-sticky\">\n <!-- Sticky elements here -->\n <ng-container #stickyCells>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-checkbox-wrapper>\n <input\n tabindex=\"-1\"\n type=\"checkbox\"\n clrCheckbox\n [ngModel]=\"selected\"\n (ngModelChange)=\"toggle($event)\"\n [id]=\"checkboxId\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"checkboxId\" class=\"clr-control-label clr-col-null\" (click)=\"clearRanges($event)\">\n <span class=\"clr-sr-only\">{{clrDgRowSelectionLabel || commonStrings.keys.select}}</span>\n </label>\n </clr-checkbox-wrapper>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n tabindex=\"-1\"\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n tabindex=\"-1\"\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n tabindex=\"-1\"\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["for"] }, { kind: "directive", type: ClrCheckbox, selector: "[clrCheckbox],[clrToggle]" }, { kind: "component", type: ClrCheckboxWrapper, selector: "clr-checkbox-wrapper,clr-toggle-wrapper" }, { kind: "directive", type: ClrRadio, selector: "[clrRadio]" }, { kind: "component", type: ClrRadioWrapper, selector: "clr-radio-wrapper" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrExpandableAnimation, selector: "clr-expandable-animation", inputs: ["clrExpandTrigger"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }] });
15337
15538
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridRow, decorators: [{
15338
15539
  type: Component,
15339
15540
  args: [{ selector: 'clr-dg-row', host: {
@@ -15345,7 +15546,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15345
15546
  DatagridIfExpandService,
15346
15547
  { provide: IfExpandService, useExisting: DatagridIfExpandService },
15347
15548
  { provide: LoadingListener, useExisting: DatagridIfExpandService },
15348
- ], template: "<!--\n We need to wrap the #rowContent in label element if we are in rowSelectionMode.\n Clicking of that wrapper label will equate to clicking on the whole row, which triggers the checkbox to toggle.\n-->\n<div\n class=\"datagrid-row-clickable\"\n *ngIf=\"selection.rowSelectionMode\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n>\n <clr-expandable-animation [clrExpandTrigger]=\"expandAnimationTrigger\" *ngIf=\"expand.expandable\">\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n </clr-expandable-animation>\n <ng-template [ngTemplateOutlet]=\"rowContent\" *ngIf=\"!expand.expandable\"></ng-template>\n</div>\n\n<clr-expandable-animation\n *ngIf=\"!selection.rowSelectionMode && expand.expandable\"\n [clrExpandTrigger]=\"expandAnimationTrigger\"\n>\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n</clr-expandable-animation>\n\n<ng-template *ngIf=\"!selection.rowSelectionMode && !expand.expandable\" [ngTemplateOutlet]=\"rowContent\"></ng-template>\n\n<!--\n We need the \"project into template\" hacks because we need this in 2 different places\n depending on whether the details replace the row or not.\n-->\n<ng-template #detail>\n <ng-content select=\"clr-dg-row-detail\"></ng-content>\n</ng-template>\n\n<ng-template #rowContent>\n <div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [class.datagrid-row-detail-open]=\"detailService.isRowOpen(item)\"\n >\n <div class=\"datagrid-row-sticky\">\n <!-- Sticky elements here -->\n <ng-container #stickyCells>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-checkbox-wrapper>\n <input\n type=\"checkbox\"\n clrCheckbox\n [ngModel]=\"selected\"\n (ngModelChange)=\"toggle($event)\"\n [id]=\"checkboxId\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"checkboxId\" class=\"clr-control-label clr-col-null\" (click)=\"clearRanges($event)\">\n <span class=\"clr-sr-only\">{{clrDgRowSelectionLabel || commonStrings.keys.select}}</span>\n </label>\n </clr-checkbox-wrapper>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n" }]
15549
+ ], template: "<!--\n We need to wrap the #rowContent in label element if we are in rowSelectionMode.\n Clicking of that wrapper label will equate to clicking on the whole row, which triggers the checkbox to toggle.\n-->\n<div\n class=\"datagrid-row-clickable\"\n *ngIf=\"selection.rowSelectionMode\"\n (mousedown)=\"clearRanges($event)\"\n (click)=\"selectRow(!selected, $event)\"\n>\n <clr-expandable-animation [clrExpandTrigger]=\"expandAnimationTrigger\" *ngIf=\"expand.expandable\">\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n </clr-expandable-animation>\n <ng-template [ngTemplateOutlet]=\"rowContent\" *ngIf=\"!expand.expandable\"></ng-template>\n</div>\n\n<clr-expandable-animation\n *ngIf=\"!selection.rowSelectionMode && expand.expandable\"\n [clrExpandTrigger]=\"expandAnimationTrigger\"\n>\n <ng-template [ngTemplateOutlet]=\"rowContent\"></ng-template>\n</clr-expandable-animation>\n\n<ng-template *ngIf=\"!selection.rowSelectionMode && !expand.expandable\" [ngTemplateOutlet]=\"rowContent\"></ng-template>\n\n<!--\n We need the \"project into template\" hacks because we need this in 2 different places\n depending on whether the details replace the row or not.\n-->\n<ng-template #detail>\n <ng-content select=\"clr-dg-row-detail\"></ng-content>\n</ng-template>\n\n<ng-template #rowContent>\n <div\n role=\"row\"\n [id]=\"id\"\n class=\"datagrid-row-master datagrid-row-flex\"\n [class.datagrid-row-detail-open]=\"detailService.isRowOpen(item)\"\n >\n <div class=\"datagrid-row-sticky\">\n <!-- Sticky elements here -->\n <ng-container #stickyCells>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-checkbox-wrapper>\n <input\n tabindex=\"-1\"\n type=\"checkbox\"\n clrCheckbox\n [ngModel]=\"selected\"\n (ngModelChange)=\"toggle($event)\"\n [id]=\"checkboxId\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"checkboxId\" class=\"clr-control-label clr-col-null\" (click)=\"clearRanges($event)\">\n <span class=\"clr-sr-only\">{{clrDgRowSelectionLabel || commonStrings.keys.select}}</span>\n </label>\n </clr-checkbox-wrapper>\n </div>\n <div\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n class=\"datagrid-select datagrid-fixed-column datagrid-cell\"\n [ngClass]=\"{ 'clr-form-control-disabled': !clrDgSelectable }\"\n role=\"gridcell\"\n >\n <clr-radio-wrapper>\n <input\n tabindex=\"-1\"\n type=\"radio\"\n clrRadio\n [id]=\"radioId\"\n [name]=\"selection.id + '-radio'\"\n [value]=\"item\"\n [(ngModel)]=\"selection.currentSingle\"\n [checked]=\"selection.currentSingle === item\"\n [disabled]=\"clrDgSelectable ? null : true\"\n [attr.aria-disabled]=\"clrDgSelectable ? null : true\"\n />\n <label class=\"clr-control-label clr-col-null\" [for]=\"radioId\">\n <span class=\"clr-sr-only\">{{ clrDgRowSelectionLabel || commonStrings.keys.select }}</span>\n </label>\n </clr-radio-wrapper>\n </div>\n <div\n *ngIf=\"rowActionService.hasActionableRow\"\n class=\"datagrid-row-actions datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-content select=\"clr-dg-action-overflow\"></ng-content>\n </div>\n <div\n *ngIf=\"globalExpandable.hasExpandableRow\"\n class=\"datagrid-expandable-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <ng-container *ngIf=\"expand.expandable\">\n <button\n tabindex=\"-1\"\n *ngIf=\"!expand.loading\"\n (click)=\"toggleExpand()\"\n type=\"button\"\n class=\"datagrid-expandable-caret-button\"\n [attr.aria-expanded]=\"expand.expanded\"\n [attr.aria-label]=\"expand.expanded ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-controls]=\"expandableId\"\n >\n <cds-icon\n shape=\"angle\"\n class=\"datagrid-expandable-caret-icon\"\n [attr.direction]=\"expand.expanded ? 'down' : 'right'\"\n [attr.title]=\"expand.expanded ? commonStrings.keys.collapse : commonStrings.keys.expand\"\n ></cds-icon>\n </button>\n <clr-spinner *ngIf=\"expand.loading\" clrSmall>{{ commonStrings.keys.loading }}</clr-spinner>\n </ng-container>\n </div>\n <div\n *ngIf=\"detailService.enabled\"\n class=\"datagrid-detail-caret datagrid-fixed-column datagrid-cell\"\n role=\"gridcell\"\n >\n <button\n tabindex=\"-1\"\n (click)=\"detailService.toggle(item, detailButton)\"\n type=\"button\"\n #detailButton\n class=\"datagrid-detail-caret-button\"\n [class.is-open]=\"detailService.isRowOpen(item)\"\n [attr.aria-label]=\"detailService.isRowOpen(item) ? clrDgDetailCloseLabel : clrDgDetailOpenLabel\"\n [attr.aria-expanded]=\"detailService.isRowOpen(item)\"\n [attr.aria-controls]=\"detailService.id\"\n aria-haspopup=\"dialog\"\n >\n <cds-icon\n shape=\"angle-double\"\n [attr.direction]=\"detailService.isRowOpen(item) ? 'left' : 'right'\"\n class=\"datagrid-detail-caret-icon\"\n [attr.title]=\"detailService.isRowOpen(item) ? commonStrings.keys.close: commonStrings.keys.open\"\n ></cds-icon>\n </button>\n </div>\n </ng-container>\n <!-- placeholder for projecting other sticky cells as pinned-->\n </div>\n <div class=\"datagrid-row-scrollable\" [ngClass]=\"{'is-replaced': replaced && expanded}\">\n <div class=\"datagrid-scrolling-cells\">\n <ng-content select=\"clr-dg-cell\"></ng-content>\n <ng-container #scrollableCells></ng-container>\n </div>\n <!-- details here when replace, re-visit when sticky container is used for pinned cells -->\n <ng-template *ngIf=\"replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n <ng-template *ngIf=\"!replaced && !expand.loading\" [ngTemplateOutlet]=\"detail\"></ng-template>\n </div>\n </div>\n</ng-template>\n\n<ng-container #calculatedCells></ng-container>\n" }]
15349
15550
  }], ctorParameters: function () { return [{ type: Selection }, { type: RowActionService }, { type: ExpandableRowsCount }, { type: DatagridIfExpandService }, { type: DetailService }, { type: DisplayModeService }, { type: i0.ViewContainerRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: ClrCommonStringsService }, { type: Items }, { type: undefined, decorators: [{
15350
15551
  type: Inject,
15351
15552
  args: [DOCUMENT]
@@ -15403,10 +15604,11 @@ var DatagridColumnChanges;
15403
15604
  (function (DatagridColumnChanges) {
15404
15605
  DatagridColumnChanges[DatagridColumnChanges["WIDTH"] = 0] = "WIDTH";
15405
15606
  DatagridColumnChanges[DatagridColumnChanges["HIDDEN"] = 1] = "HIDDEN";
15607
+ DatagridColumnChanges[DatagridColumnChanges["INITIALIZE"] = 2] = "INITIALIZE";
15406
15608
  })(DatagridColumnChanges || (DatagridColumnChanges = {}));
15407
15609
  const ALL_COLUMN_CHANGES = Object.keys(DatagridColumnChanges)
15408
15610
  .map(key => DatagridColumnChanges[key])
15409
- .filter(key => key === parseInt(key, 10)); // extracts only integer keys
15611
+ .filter(key => key === parseInt(key, 10) && key !== DatagridColumnChanges.INITIALIZE); // extracts only integer keys
15410
15612
 
15411
15613
  /*
15412
15614
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
@@ -15417,6 +15619,7 @@ const ALL_COLUMN_CHANGES = Object.keys(DatagridColumnChanges)
15417
15619
  class ColumnsService {
15418
15620
  constructor() {
15419
15621
  this.columns = [];
15622
+ this.columnsStateChange = new BehaviorSubject(null);
15420
15623
  this._cache = [];
15421
15624
  }
15422
15625
  get columnStates() {
@@ -15438,7 +15641,9 @@ class ColumnsService {
15438
15641
  resetToLastCache() {
15439
15642
  this._cache.forEach((state, index) => {
15440
15643
  // Just emit the exact value from the cache
15441
- this.columns[index].next({ ...state, changes: ALL_COLUMN_CHANGES });
15644
+ const cachedState = { ...state, changes: ALL_COLUMN_CHANGES };
15645
+ this.columns[index].next(cachedState);
15646
+ this.columnsStateChange.next(cachedState);
15442
15647
  });
15443
15648
  this._cache = [];
15444
15649
  }
@@ -15450,7 +15655,9 @@ class ColumnsService {
15450
15655
  this.emitStateChange(this.columns[columnIndex], diff);
15451
15656
  }
15452
15657
  emitStateChange(column, diff) {
15453
- column.next({ ...column.value, ...diff });
15658
+ const changedState = { ...column.value, ...diff };
15659
+ column.next(changedState);
15660
+ this.columnsStateChange.next(changedState);
15454
15661
  }
15455
15662
  }
15456
15663
  ColumnsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ColumnsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
@@ -15526,188 +15733,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
15526
15733
  type: Injectable
15527
15734
  }], ctorParameters: function () { return [{ type: FiltersProvider }, { type: Sort }, { type: Page }, { type: StateDebouncer }]; } });
15528
15735
 
15529
- /*
15530
- * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
15531
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
15532
- * This software is released under MIT license.
15533
- * The full license information can be found in LICENSE in the root directory of this project.
15534
- */
15535
- function getTabableItems(el) {
15536
- const tabableSelector = [
15537
- 'a[href]',
15538
- 'area[href]',
15539
- 'input:not([disabled])',
15540
- 'button:not([disabled])',
15541
- 'select:not([disabled])',
15542
- 'textarea:not([disabled])',
15543
- 'iframe',
15544
- 'object',
15545
- 'embed',
15546
- '*[tabindex]',
15547
- '*[contenteditable=true]',
15548
- '[role=button]:not([disabled])',
15549
- ].join(',');
15550
- return Array.from(el.querySelectorAll(tabableSelector));
15551
- }
15552
- class KeyNavigationGridController {
15553
- constructor(zone) {
15554
- this.zone = zone;
15555
- this.listenersAdded = false;
15556
- this.destroy$ = new Subject();
15557
- this._activeCell = null;
15558
- this.config = {
15559
- keyGridRows: '[role=row]:not(.datagrid-placeholder)',
15560
- keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
15561
- keyGrid: '[role=grid]',
15562
- };
15563
- }
15564
- get grid() {
15565
- return this.host?.querySelector(this.config.keyGrid);
15566
- }
15567
- get rows() {
15568
- return this.host?.querySelectorAll(this.config.keyGridRows);
15569
- }
15570
- get cells() {
15571
- return this.host?.querySelectorAll(this.config.keyGridCells);
15572
- }
15573
- ngOnDestroy() {
15574
- this.destroy$.next();
15575
- this.destroy$.complete();
15576
- }
15577
- addListeners() {
15578
- if (this.listenersAdded) {
15579
- return;
15580
- }
15581
- this.zone.runOutsideAngular(() => {
15582
- fromEvent(this.grid, 'mousedown')
15583
- .pipe(takeUntil(this.destroy$))
15584
- .subscribe((e) => {
15585
- // preserve right click for context menus & keyboard mouse control https://apple.stackexchange.com/questions/32715/how-do-i-open-the-context-menu-from-a-mac-keyboard
15586
- if (e.buttons === 1 && !e.ctrlKey) {
15587
- const activeCell = this.cells
15588
- ? Array.from(this.cells).find(c => c === e.target || c === e.target.closest(this.config.keyGridCells))
15589
- : null;
15590
- if (activeCell) {
15591
- this.setActiveCell(activeCell);
15592
- }
15593
- }
15594
- });
15595
- fromEvent(this.grid, 'wheel')
15596
- .pipe(takeUntil(this.destroy$))
15597
- .subscribe(() => {
15598
- this.removeActiveCell();
15599
- });
15600
- fromEvent(this.grid, 'keydown')
15601
- .pipe(takeUntil(this.destroy$))
15602
- .subscribe((e) => {
15603
- // Skip column resize events
15604
- if (e.target.classList.contains('drag-handle') &&
15605
- (e.code === 'ArrowLeft' || e.code === 'ArrowRight')) {
15606
- return;
15607
- }
15608
- if (e.code === 'ArrowUp' ||
15609
- e.code === 'ArrowDown' ||
15610
- e.code === 'ArrowLeft' ||
15611
- e.code === 'ArrowRight' ||
15612
- e.code === 'End' ||
15613
- e.code === 'Home' ||
15614
- e.code === 'PageUp' ||
15615
- e.code === 'PageDown') {
15616
- const { x, y } = this.getNextItemCoordinate(e);
15617
- const activeItem = this.rows
15618
- ? Array.from(this.rows[y].querySelectorAll(this.config.keyGridCells))[x]
15619
- : null;
15620
- if (activeItem) {
15621
- this.setActiveCell(activeItem);
15622
- }
15623
- e.preventDefault();
15624
- }
15625
- });
15626
- });
15627
- this.listenersAdded = true;
15628
- }
15629
- initializeKeyGrid(host) {
15630
- this.host = host;
15631
- this.addListeners();
15632
- this.resetKeyGrid();
15633
- }
15634
- resetKeyGrid() {
15635
- this.cells?.forEach((i) => i.setAttribute('tabindex', '-1'));
15636
- const firstCell = this.cells ? this.cells[0] : null;
15637
- firstCell?.setAttribute('tabindex', '0');
15638
- }
15639
- removeActiveCell() {
15640
- this._activeCell = null;
15641
- }
15642
- getActiveCell() {
15643
- return this._activeCell;
15644
- }
15645
- setActiveCell(activeCell) {
15646
- const prior = this.cells ? Array.from(this.cells).find(c => c.getAttribute('tabindex') === '0') : null;
15647
- if (prior) {
15648
- prior.setAttribute('tabindex', '-1');
15649
- }
15650
- activeCell.setAttribute('tabindex', '0');
15651
- const items = getTabableItems(activeCell);
15652
- const item = activeCell.getAttribute('role') !== 'columnheader' && items[0] ? items[0] : activeCell;
15653
- item.focus();
15654
- this._activeCell = item;
15655
- }
15656
- getNextItemCoordinate(e) {
15657
- let currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
15658
- if (e.code === 'Tab') {
15659
- currentCell = document.activeElement;
15660
- }
15661
- const currentRow = this.rows && currentCell ? Array.from(this.rows).find(r => r.contains(currentCell)) : null;
15662
- const numOfRows = this.rows ? this.rows.length - 1 : 0;
15663
- const numOfColumns = this.cells ? Math.floor(this.cells.length / this.rows.length - 1) : 0;
15664
- let x = currentRow && currentCell
15665
- ? Array.from(currentRow.querySelectorAll(this.config.keyGridCells)).indexOf(currentCell)
15666
- : 0;
15667
- let y = currentRow && currentCell && this.rows ? Array.from(this.rows).indexOf(currentRow) : 0;
15668
- const dir = this.host.dir;
15669
- const inlineStart = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
15670
- const inlineEnd = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
15671
- const itemsPerPage = Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.rows[0].clientHeight) - 1 || 0;
15672
- if (e.code === 'ArrowUp' && y !== 0) {
15673
- y = y - 1;
15674
- }
15675
- else if (e.code === 'ArrowDown' && y < numOfRows) {
15676
- y = y + 1;
15677
- }
15678
- else if (e.code === inlineStart && x !== 0) {
15679
- x = x - 1;
15680
- }
15681
- else if (e.code === inlineEnd && x < numOfColumns) {
15682
- x = x + 1;
15683
- }
15684
- else if (e.code === 'End') {
15685
- x = numOfColumns;
15686
- if (e.ctrlKey) {
15687
- y = numOfRows;
15688
- }
15689
- }
15690
- else if (e.code === 'Home') {
15691
- x = 0;
15692
- if (e.ctrlKey) {
15693
- y = 0;
15694
- }
15695
- }
15696
- else if (e.code === 'PageUp') {
15697
- y = y - itemsPerPage > 0 ? y - itemsPerPage + 1 : 1;
15698
- }
15699
- else if (e.code === 'PageDown') {
15700
- y = y + itemsPerPage < numOfRows ? y + itemsPerPage : numOfRows;
15701
- }
15702
- return { x, y };
15703
- }
15704
- }
15705
- KeyNavigationGridController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
15706
- KeyNavigationGridController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController });
15707
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: KeyNavigationGridController, decorators: [{
15708
- type: Injectable
15709
- }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
15710
-
15711
15736
  /*
15712
15737
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
15713
15738
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -15741,7 +15766,6 @@ class DatagridCellRenderer {
15741
15766
  }
15742
15767
  }
15743
15768
  resetState(state) {
15744
- state.changes = ALL_COLUMN_CHANGES;
15745
15769
  this.setWidth(state);
15746
15770
  this.setHidden(state);
15747
15771
  }
@@ -15976,12 +16000,16 @@ class ClrDatagrid {
15976
16000
  */
15977
16001
  if (row) {
15978
16002
  this.detailService.open(row.item, row.detailButton.nativeElement);
16003
+ // always keep open when virtual scroll is available otherwise close it
15979
16004
  }
15980
- else if (!this.hasVirtualScroller || !row) {
15981
- this.detailService.close();
16005
+ else if (!this.hasVirtualScroller) {
16006
+ // Using setTimeout to make sure the inner cycles in rows are done
16007
+ setTimeout(() => {
16008
+ this.detailService.close();
16009
+ });
15982
16010
  }
15983
16011
  }
15984
- // retain active cell when navigating with PageUp and PageDown buttons in virtual scroller
16012
+ // retain active cell when navigating with Up/Down Arrows, PageUp and PageDown buttons in virtual scroller
15985
16013
  const active = this.keyNavigation.getActiveCell();
15986
16014
  if (active) {
15987
16015
  this.zone.runOutsideAngular(() => {
@@ -16068,6 +16096,13 @@ class ClrDatagrid {
16068
16096
  ngOnDestroy() {
16069
16097
  this._subscriptions.forEach((sub) => sub.unsubscribe());
16070
16098
  }
16099
+ toggleAllSelected($event) {
16100
+ $event.preventDefault();
16101
+ if (this.hasVirtualScroller) {
16102
+ return;
16103
+ }
16104
+ this.allSelected = !this.allSelected;
16105
+ }
16071
16106
  resize() {
16072
16107
  this.organizer.resize();
16073
16108
  }
@@ -16095,7 +16130,7 @@ ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
16095
16130
  ColumnsService,
16096
16131
  DisplayModeService,
16097
16132
  KeyNavigationGridController,
16098
- ], queries: [{ propertyName: "iterator", first: true, predicate: ClrDatagridItems, descendants: true }, { propertyName: "placeholder", first: true, predicate: ClrDatagridPlaceholder, descendants: true }, { propertyName: "columns", predicate: ClrDatagridColumn }, { propertyName: "rows", predicate: ClrDatagridRow }], viewQueries: [{ propertyName: "datagrid", first: true, predicate: ["datagrid"], descendants: true, read: ElementRef }, { propertyName: "datagridTable", first: true, predicate: ["datagridTable"], descendants: true, read: ElementRef }, { propertyName: "scrollableColumns", first: true, predicate: ["scrollableColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedDisplayColumns", first: true, predicate: ["projectedDisplayColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedCalculationColumns", first: true, predicate: ["projectedCalculationColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_displayedRows", first: true, predicate: ["displayedRows"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculationRows", first: true, predicate: ["calculationRows"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2024 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"allSelected = !allSelected; $event.preventDefault()\"\n >\n <div *ngIf=\"!hasVirtualScroller\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-loading-more-items-row\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell class=\"datagrid-loading-more-items-cell\">\n <clr-spinner [clrMedium]=\"true\"></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-loading-more-items-row\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell class=\"datagrid-loading-more-items-cell\">\n <clr-spinner [clrMedium]=\"true\"></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["for"] }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "component", type: ClrDatagridCell, selector: "clr-dg-cell" }, { kind: "component", type: ClrDatagridPlaceholder, selector: "clr-dg-placeholder" }, { kind: "component", type: ClrDatagridRow, selector: "clr-dg-row", inputs: ["clrDgItem", "clrDgSelectable", "clrDgSelected", "clrDgExpanded", "clrDgDetailOpenLabel", "clrDgDetailCloseLabel", "clrDgRowSelectionLabel"], outputs: ["clrDgSelectedChange", "clrDgExpandedChange"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }, { kind: "directive", type: DatagridCellRenderer, selector: "clr-dg-cell" }, { kind: "directive", type: DatagridRowRenderer, selector: "clr-dg-row, clr-dg-row-detail" }, { kind: "directive", type: ActionableOompaLoompa, selector: "clr-datagrid, clr-dg-row" }, { kind: "directive", type: ExpandableOompaLoompa, selector: "clr-datagrid, clr-dg-row" }] });
16133
+ ], queries: [{ propertyName: "iterator", first: true, predicate: ClrDatagridItems, descendants: true }, { propertyName: "placeholder", first: true, predicate: ClrDatagridPlaceholder, descendants: true }, { propertyName: "columns", predicate: ClrDatagridColumn }, { propertyName: "rows", predicate: ClrDatagridRow }], viewQueries: [{ propertyName: "datagrid", first: true, predicate: ["datagrid"], descendants: true, read: ElementRef }, { propertyName: "datagridTable", first: true, predicate: ["datagridTable"], descendants: true, read: ElementRef }, { propertyName: "scrollableColumns", first: true, predicate: ["scrollableColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedDisplayColumns", first: true, predicate: ["projectedDisplayColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_projectedCalculationColumns", first: true, predicate: ["projectedCalculationColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "_displayedRows", first: true, predicate: ["displayedRows"], descendants: true, read: ViewContainerRef }, { propertyName: "_calculationRows", first: true, predicate: ["calculationRows"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2024 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"toggleAllSelected($event)\"\n >\n <div *ngIf=\"!hasVirtualScroller\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: ClrLabel, selector: "label", inputs: ["for"] }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }, { kind: "component", type: ClrDatagridCell, selector: "clr-dg-cell" }, { kind: "component", type: ClrDatagridPlaceholder, selector: "clr-dg-placeholder" }, { kind: "component", type: ClrDatagridRow, selector: "clr-dg-row", inputs: ["clrDgItem", "clrDgSelectable", "clrDgSelected", "clrDgExpanded", "clrDgDetailOpenLabel", "clrDgDetailCloseLabel", "clrDgRowSelectionLabel"], outputs: ["clrDgSelectedChange", "clrDgExpandedChange"] }, { kind: "directive", type: ClrDatagridSelectionCellDirective, selector: ".datagrid-select" }, { kind: "directive", type: DatagridCellRenderer, selector: "clr-dg-cell" }, { kind: "directive", type: DatagridRowRenderer, selector: "clr-dg-row, clr-dg-row-detail" }, { kind: "directive", type: ActionableOompaLoompa, selector: "clr-datagrid, clr-dg-row" }, { kind: "directive", type: ExpandableOompaLoompa, selector: "clr-datagrid, clr-dg-row" }] });
16099
16134
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagrid, decorators: [{
16100
16135
  type: Component,
16101
16136
  args: [{ selector: 'clr-datagrid', providers: [
@@ -16117,7 +16152,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16117
16152
  ], host: {
16118
16153
  '[class.datagrid-host]': 'true',
16119
16154
  '[class.datagrid-detail-open]': 'detailService.isOpen',
16120
- }, template: "<!--\n ~ Copyright (c) 2016-2024 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"allSelected = !allSelected; $event.preventDefault()\"\n >\n <div *ngIf=\"!hasVirtualScroller\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-loading-more-items-row\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell class=\"datagrid-loading-more-items-cell\">\n <clr-spinner [clrMedium]=\"true\"></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-loading-more-items-row\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell class=\"datagrid-loading-more-items-cell\">\n <clr-spinner [clrMedium]=\"true\"></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n" }]
16155
+ }, template: "<!--\n ~ Copyright (c) 2016-2024 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-content select=\"clr-dg-action-bar\"></ng-content>\n<div class=\"datagrid-outer-wrapper\">\n <div class=\"datagrid-inner-wrapper\">\n <div class=\"datagrid\" #datagrid [attr.aria-hidden]=\"detailService.isOpen ? true : null\">\n <div class=\"datagrid-table-wrapper\">\n <div role=\"grid\" class=\"datagrid-table\" tabindex=\"-1\" #datagridTable>\n <div role=\"rowgroup\" class=\"datagrid-header\">\n <div role=\"row\" class=\"datagrid-row\">\n <div class=\"datagrid-row-master datagrid-row-flex\">\n <div class=\"datagrid-row-sticky\">\n <!--header for datagrid where you can select multiple rows -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Multi\"\n (keydown.space)=\"toggleAllSelected($event)\"\n >\n <div *ngIf=\"!hasVirtualScroller\" class=\"clr-checkbox-wrapper\">\n <!-- We need to move focus and space-key handling to the parent because of keyboard arrow key navigation,\n which is not able to transfer focus directly on the input when focused with the tab key -->\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\n tabindex=\"-1\"\n />\n <!-- Usage of class clr-col-null here prevents clr-col-* classes from being added when a datagrid is wrapped inside clrForm -->\n <label [for]=\"selectAllId\" class=\"clr-control-label clr-col-null\">\n <span class=\"clr-sr-only\">{{commonStrings.keys.selectAll}}</span>\n </label>\n </div>\n\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for datagrid where you can select one row only -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-select datagrid-fixed-column\"\n *ngIf=\"selection.selectionType === SELECTION_TYPE.Single\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleSelectionAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for single row action; only displayType if we have at least one actionable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-row-actions datagrid-fixed-column\"\n *ngIf=\"rowActionService.hasActionableRow\"\n >\n <div class=\"clr-sr-only\">{{clrDgSingleActionableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n <!-- header for carets; only displayType if we have at least one expandable row in datagrid -->\n <div\n role=\"columnheader\"\n class=\"datagrid-column datagrid-expandable-caret datagrid-fixed-column\"\n *ngIf=\"expandableRows.hasExpandableRow || detailService.enabled\"\n >\n <div class=\"clr-sr-only\">{{clrDetailExpandableAriaLabel}}</div>\n <div class=\"datagrid-column-separator\"></div>\n </div>\n </div>\n <div class=\"datagrid-row-scrollable\">\n <ng-container #projectedDisplayColumns></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <div role=\"presentation\" class=\"datagrid-rows\">\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <ng-container #displayedRows></ng-container>\n\n <clr-dg-row class=\"datagrid-row-loading\" *ngIf=\"loadingMoreItems\">\n <clr-dg-cell>\n <clr-spinner clrMedium></clr-spinner>\n <span>{{ commonStrings.keys.loading }}</span>\n </clr-dg-cell>\n </clr-dg-row>\n\n <!-- Custom placeholder overrides the default empty one -->\n <ng-content select=\"clr-dg-placeholder\"></ng-content>\n <clr-dg-placeholder *ngIf=\"!placeholder\"></clr-dg-placeholder>\n </div>\n </div>\n </div>\n </div>\n <ng-content select=\"clr-dg-footer\"></ng-content>\n <div class=\"datagrid-spinner\" *ngIf=\"loading\">\n <clr-spinner clrMedium>Loading</clr-spinner>\n </div>\n </div>\n <ng-content select=\"[clrIfDetail],clr-dg-detail\"></ng-content>\n</div>\n\n<div class=\"datagrid-calculation-table\">\n <div class=\"datagrid-calculation-header\">\n <ng-container #projectedCalculationColumns></ng-container>\n </div>\n <ng-container #calculationRows></ng-container>\n</div>\n" }]
16121
16156
  }], ctorParameters: function () { return [{ type: DatagridRenderOrganizer }, { type: Items }, { type: ExpandableRowsCount }, { type: Selection }, { type: RowActionService }, { type: StateProvider }, { type: DisplayModeService }, { type: i0.Renderer2 }, { type: DetailService }, { type: undefined, decorators: [{
16122
16157
  type: Inject,
16123
16158
  args: [DOCUMENT]
@@ -16286,6 +16321,7 @@ class ClrDatagridActionOverflow {
16286
16321
  ClrDatagridActionOverflow.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridActionOverflow, deps: [{ token: RowActionService }, { token: ClrCommonStringsService }, { token: PLATFORM_ID }, { token: i0.NgZone }, { token: ClrPopoverToggleService }], target: i0.ɵɵFactoryTarget.Component });
16287
16322
  ClrDatagridActionOverflow.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridActionOverflow, selector: "clr-dg-action-overflow", inputs: { buttonLabel: ["clrDgActionOverflowButtonLabel", "buttonLabel"], open: ["clrDgActionOverflowOpen", "open"] }, outputs: { openChange: "clrDgActionOverflowOpenChange" }, viewQueries: [{ propertyName: "keyFocus", first: true, predicate: ClrKeyFocus, descendants: true }], hostDirectives: [{ directive: ClrPopoverHostDirective }], ngImport: i0, template: `
16288
16323
  <button
16324
+ tabindex="-1"
16289
16325
  class="datagrid-action-toggle"
16290
16326
  type="button"
16291
16327
  role="button"
@@ -16320,6 +16356,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16320
16356
  hostDirectives: [ClrPopoverHostDirective],
16321
16357
  template: `
16322
16358
  <button
16359
+ tabindex="-1"
16323
16360
  class="datagrid-action-toggle"
16324
16361
  type="button"
16325
16362
  role="button"
@@ -16665,10 +16702,13 @@ class ClrDatagridDetailHeader {
16665
16702
  get titleId() {
16666
16703
  return `${this.detailService.id}-title`;
16667
16704
  }
16705
+ ngAfterViewInit() {
16706
+ this.title.nativeElement.focus();
16707
+ }
16668
16708
  }
16669
16709
  ClrDatagridDetailHeader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridDetailHeader, deps: [{ token: DetailService }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
16670
- ClrDatagridDetailHeader.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridDetailHeader, selector: "clr-dg-detail-header", host: { properties: { "class.datagrid-detail-header": "true" } }, ngImport: i0, template: `
16671
- <div class="datagrid-detail-header-title" cdkFocusInitial tabindex="-1" [id]="titleId">
16710
+ ClrDatagridDetailHeader.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridDetailHeader, selector: "clr-dg-detail-header", host: { properties: { "class.datagrid-detail-header": "true" } }, viewQueries: [{ propertyName: "title", first: true, predicate: ["title"], descendants: true }], ngImport: i0, template: `
16711
+ <div #title class="datagrid-detail-header-title" tabindex="-1" [id]="titleId">
16672
16712
  <ng-content></ng-content>
16673
16713
  </div>
16674
16714
  <div class="datagrid-detail-pane-close">
@@ -16690,7 +16730,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16690
16730
  '[class.datagrid-detail-header]': 'true',
16691
16731
  },
16692
16732
  template: `
16693
- <div class="datagrid-detail-header-title" cdkFocusInitial tabindex="-1" [id]="titleId">
16733
+ <div #title class="datagrid-detail-header-title" tabindex="-1" [id]="titleId">
16694
16734
  <ng-content></ng-content>
16695
16735
  </div>
16696
16736
  <div class="datagrid-detail-pane-close">
@@ -16705,7 +16745,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16705
16745
  </div>
16706
16746
  `,
16707
16747
  }]
16708
- }], ctorParameters: function () { return [{ type: DetailService }, { type: ClrCommonStringsService }]; } });
16748
+ }], ctorParameters: function () { return [{ type: DetailService }, { type: ClrCommonStringsService }]; }, propDecorators: { title: [{
16749
+ type: ViewChild,
16750
+ args: ['title']
16751
+ }] } });
16709
16752
 
16710
16753
  /*
16711
16754
  * Copyright (c) 2016-2024 Broadcom. All Rights Reserved.
@@ -16726,7 +16769,7 @@ ClrDatagridDetail.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", versio
16726
16769
  ClrDatagridDetail.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridDetail, selector: "clr-dg-detail", host: { properties: { "class.datagrid-detail-pane": "true" } }, queries: [{ propertyName: "header", first: true, predicate: ClrDatagridDetailHeader, descendants: true }], ngImport: i0, template: `
16727
16770
  <div
16728
16771
  cdkTrapFocus
16729
- [cdkTrapFocusAutoCapture]="true"
16772
+ [cdkTrapFocusAutoCapture]="!header"
16730
16773
  class="datagrid-detail-pane-content"
16731
16774
  *ngIf="detailService.isOpen"
16732
16775
  role="dialog"
@@ -16751,7 +16794,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
16751
16794
  template: `
16752
16795
  <div
16753
16796
  cdkTrapFocus
16754
- [cdkTrapFocusAutoCapture]="true"
16797
+ [cdkTrapFocusAutoCapture]="!header"
16755
16798
  class="datagrid-detail-pane-content"
16756
16799
  *ngIf="detailService.isOpen"
16757
16800
  role="dialog"
@@ -17603,7 +17646,7 @@ const defaultCdkFixedSizeVirtualScrollInputs = {
17603
17646
  maxBufferPx: 400,
17604
17647
  };
17605
17648
  class ClrDatagridVirtualScrollDirective {
17606
- constructor(changeDetectorRef, iterableDiffers, items, ngZone, templateRef, viewContainerRef, directionality, scrollDispatcher, viewportRuler, datagrid, injector) {
17649
+ constructor(changeDetectorRef, iterableDiffers, items, ngZone, templateRef, viewContainerRef, directionality, scrollDispatcher, viewportRuler, datagrid, columnsService, injector) {
17607
17650
  this.changeDetectorRef = changeDetectorRef;
17608
17651
  this.iterableDiffers = iterableDiffers;
17609
17652
  this.items = items;
@@ -17614,6 +17657,7 @@ class ClrDatagridVirtualScrollDirective {
17614
17657
  this.scrollDispatcher = scrollDispatcher;
17615
17658
  this.viewportRuler = viewportRuler;
17616
17659
  this.datagrid = datagrid;
17660
+ this.columnsService = columnsService;
17617
17661
  this.injector = injector;
17618
17662
  this.renderedRangeChange = new EventEmitter();
17619
17663
  this._cdkFixedSizeVirtualScrollInputs = { ...defaultCdkFixedSizeVirtualScrollInputs };
@@ -17626,12 +17670,16 @@ class ClrDatagridVirtualScrollDirective {
17626
17670
  }
17627
17671
  });
17628
17672
  });
17673
+ this.viewRepeater = new _RecycleViewRepeaterStrategy();
17629
17674
  this.cdkVirtualForInputs = {
17630
17675
  cdkVirtualForTrackBy: index => index,
17631
17676
  };
17632
17677
  this.items.smartenUp();
17633
17678
  this.datagrid.hasVirtualScroller = true;
17679
+ this.datagrid.detailService.preventFocusScroll = true;
17634
17680
  this.datagridElementRef = this.datagrid.el;
17681
+ // default
17682
+ this.cdkVirtualForTemplateCacheSize = 20;
17635
17683
  this.mutationChanges.observe(this.datagridElementRef.nativeElement, {
17636
17684
  attributeFilter: ['class'],
17637
17685
  attributeOldValue: true,
@@ -17691,7 +17739,7 @@ class ClrDatagridVirtualScrollDirective {
17691
17739
  ngAfterViewInit() {
17692
17740
  this.injector.runInContext(() => {
17693
17741
  this.virtualScrollViewport = this.createVirtualScrollViewportForDatagrid(this.changeDetectorRef, this.ngZone, this.directionality, this.scrollDispatcher, this.viewportRuler, this.datagridElementRef, this.virtualScrollStrategy);
17694
- this.cdkVirtualFor = new CdkVirtualForOf(this.viewContainerRef, this.templateRef, this.iterableDiffers, new _RecycleViewRepeaterStrategy(), this.virtualScrollViewport, this.ngZone);
17742
+ this.cdkVirtualFor = new CdkVirtualForOf(this.viewContainerRef, this.templateRef, this.iterableDiffers, this.viewRepeater, this.virtualScrollViewport, this.ngZone);
17695
17743
  this.virtualScrollViewport.ngOnInit();
17696
17744
  });
17697
17745
  this.gridRoleElement = this.datagridElementRef.nativeElement.querySelector('[role="grid"]');
@@ -17706,6 +17754,8 @@ class ClrDatagridVirtualScrollDirective {
17706
17754
  if (datagridState.filters) {
17707
17755
  this.virtualScrollViewport.scrollToIndex(0);
17708
17756
  }
17757
+ }), this.columnsService.columnsStateChange.subscribe(() => {
17758
+ this.viewRepeater.detach();
17709
17759
  }));
17710
17760
  }
17711
17761
  ngDoCheck() {
@@ -17777,7 +17827,7 @@ class ClrDatagridVirtualScrollDirective {
17777
17827
  return virtualScrollViewport;
17778
17828
  }
17779
17829
  }
17780
- ClrDatagridVirtualScrollDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.IterableDiffers }, { token: Items, skipSelf: true }, { token: i0.NgZone }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i2.Directionality }, { token: i3$1.ScrollDispatcher }, { token: i3$1.ViewportRuler }, { token: ClrDatagrid }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
17830
+ ClrDatagridVirtualScrollDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.IterableDiffers }, { token: Items, skipSelf: true }, { token: i0.NgZone }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i2.Directionality }, { token: i3$1.ScrollDispatcher }, { token: i3$1.ViewportRuler }, { token: ClrDatagrid }, { token: ColumnsService }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
17781
17831
  ClrDatagridVirtualScrollDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridVirtualScrollDirective, selector: "[ClrVirtualScroll]", inputs: { cdkVirtualForOf: ["clrVirtualRowsOf", "cdkVirtualForOf"], cdkVirtualForTrackBy: ["clrVirtualRowsTrackBy", "cdkVirtualForTrackBy"], cdkVirtualForTemplate: ["clrVirtualRowsTemplate", "cdkVirtualForTemplate"], cdkVirtualForTemplateCacheSize: ["clrVirtualRowsTemplateCacheSize", "cdkVirtualForTemplateCacheSize"], itemSize: ["clrVirtualRowsItemSize", "itemSize"], minBufferPx: ["clrVirtualRowsMinBufferPx", "minBufferPx"], maxBufferPx: ["clrVirtualRowsMaxBufferPx", "maxBufferPx"] }, outputs: { renderedRangeChange: "renderedRangeChange" }, providers: [Items], ngImport: i0 });
17782
17832
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridVirtualScrollDirective, decorators: [{
17783
17833
  type: Directive,
@@ -17787,7 +17837,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
17787
17837
  }]
17788
17838
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.IterableDiffers }, { type: Items, decorators: [{
17789
17839
  type: SkipSelf
17790
- }] }, { type: i0.NgZone }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i2.Directionality }, { type: i3$1.ScrollDispatcher }, { type: i3$1.ViewportRuler }, { type: ClrDatagrid }, { type: i0.EnvironmentInjector }]; }, propDecorators: { renderedRangeChange: [{
17840
+ }] }, { type: i0.NgZone }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i2.Directionality }, { type: i3$1.ScrollDispatcher }, { type: i3$1.ViewportRuler }, { type: ClrDatagrid }, { type: ColumnsService }, { type: i0.EnvironmentInjector }]; }, propDecorators: { renderedRangeChange: [{
17791
17841
  type: Output
17792
17842
  }], cdkVirtualForOf: [{
17793
17843
  type: Input,
@@ -18012,6 +18062,9 @@ class DatagridMainRenderer {
18012
18062
  this.subscriptions.push(this.detailService.stateChange.subscribe(state => this.toggleDetailPane(state)));
18013
18063
  this.subscriptions.push(this.items.change.subscribe(() => (this.shouldStabilizeColumns = true)));
18014
18064
  }
18065
+ ngOnInit() {
18066
+ this.columnsService.columnsStateChange.subscribe(change => this.columnStateChanged(change));
18067
+ }
18015
18068
  ngAfterContentInit() {
18016
18069
  this.setupColumns();
18017
18070
  this.subscriptions.push(this.headers.changes.subscribe(() => {
@@ -18021,7 +18074,6 @@ class DatagridMainRenderer {
18021
18074
  this.columnsSizesStable = false;
18022
18075
  this.stabilizeColumns();
18023
18076
  }));
18024
- this.listenForColumnChanges();
18025
18077
  }
18026
18078
  // Initialize and set Table width for horizontal scrolling here.
18027
18079
  ngAfterViewInit() {
@@ -18063,7 +18115,10 @@ class DatagridMainRenderer {
18063
18115
  setupColumns() {
18064
18116
  this.headers.forEach((header, index) => header.setColumnState(index));
18065
18117
  this.columnsService.columns.splice(this.headers.length); // Trim any old columns
18066
- this.rows.forEach(row => row.setCellsState());
18118
+ // Sets columnIndex for each column
18119
+ this.columnsService.columns.forEach((column, index) => {
18120
+ this.columnsService.emitStateChange(column, { changes: [DatagridColumnChanges.INITIALIZE], columnIndex: index });
18121
+ });
18067
18122
  }
18068
18123
  shouldComputeHeight() {
18069
18124
  if (!this._heightSet && this.page.size > 0) {
@@ -18120,6 +18175,10 @@ class DatagridMainRenderer {
18120
18175
  });
18121
18176
  }
18122
18177
  columnStateChanged(state) {
18178
+ // eslint-disable-next-line eqeqeq
18179
+ if (!this.headers || state.columnIndex == null) {
18180
+ return;
18181
+ }
18123
18182
  const columnIndex = state.columnIndex;
18124
18183
  if (state.changes && state.changes.length) {
18125
18184
  state.changes.forEach(change => {
@@ -18127,7 +18186,7 @@ class DatagridMainRenderer {
18127
18186
  case DatagridColumnChanges.WIDTH:
18128
18187
  this.headers.get(columnIndex).setWidth(state);
18129
18188
  this.rows.forEach(row => {
18130
- if (row.cells && row.cells.length) {
18189
+ if (row?.cells.length === this.columnsService.columns.length) {
18131
18190
  row.cells.get(columnIndex).setWidth(state);
18132
18191
  }
18133
18192
  });
@@ -18141,23 +18200,20 @@ class DatagridMainRenderer {
18141
18200
  });
18142
18201
  this.keyNavigation.resetKeyGrid();
18143
18202
  break;
18203
+ case DatagridColumnChanges.INITIALIZE:
18204
+ if (state.hideable && state.hidden) {
18205
+ this.headers.get(columnIndex).setHidden(state);
18206
+ this.rows.forEach(row => {
18207
+ row.setCellsState();
18208
+ });
18209
+ }
18210
+ break;
18144
18211
  default:
18145
18212
  break;
18146
18213
  }
18147
18214
  });
18148
18215
  }
18149
18216
  }
18150
- listenForColumnChanges() {
18151
- this.columnsService.columns.forEach((column, index) => {
18152
- this.columnsService.emitStateChange(column, { changes: [], columnIndex: index });
18153
- });
18154
- /*
18155
- Merges all column subject so we can track them at once
18156
- and receive only the changed column as result
18157
- */
18158
- const columnChanges = merge(...this.columnsService.columns);
18159
- this.subscriptions.push(columnChanges.subscribe(change => this.columnStateChanged(change)));
18160
- }
18161
18217
  /**
18162
18218
  * Triggers a whole re-rendring cycle to set column sizes, if needed.
18163
18219
  */
@@ -24463,13 +24519,13 @@ class ClrTimeline {
24463
24519
  }
24464
24520
  }
24465
24521
  ClrTimeline.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTimeline, deps: [], target: i0.ɵɵFactoryTarget.Component });
24466
- ClrTimeline.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTimeline, selector: "clr-timeline", inputs: { layout: ["clrLayout", "layout"] }, host: { properties: { "class.clr-timeline": "true", "class.clr-timeline-vertical": "this.isVertical" } }, providers: [TimelineIconAttributeService], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true });
24522
+ ClrTimeline.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTimeline, selector: "clr-timeline", inputs: { layout: ["clrLayout", "layout"] }, host: { properties: { "class.clr-timeline": "true", "attr.role": "\"list\"", "class.clr-timeline-vertical": "this.isVertical" } }, providers: [TimelineIconAttributeService], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true });
24467
24523
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTimeline, decorators: [{
24468
24524
  type: Component,
24469
24525
  args: [{
24470
24526
  selector: 'clr-timeline',
24471
24527
  template: `<ng-content></ng-content>`,
24472
- host: { '[class.clr-timeline]': 'true' },
24528
+ host: { '[class.clr-timeline]': 'true', '[attr.role]': '"list"' },
24473
24529
  providers: [TimelineIconAttributeService],
24474
24530
  }]
24475
24531
  }], propDecorators: { layout: [{
@@ -24540,7 +24596,7 @@ class ClrTimelineStep {
24540
24596
  }
24541
24597
  }
24542
24598
  ClrTimelineStep.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrTimelineStep, deps: [{ token: TimelineIconAttributeService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
24543
- ClrTimelineStep.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTimelineStep, selector: "clr-timeline-step", inputs: { state: ["clrState", "state"] }, host: { properties: { "class.clr-timeline-step": "true" } }, queries: [{ propertyName: "stepTitle", first: true, predicate: ClrTimelineStepTitle, descendants: true, read: ElementRef }], ngImport: i0, template: `
24599
+ ClrTimelineStep.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrTimelineStep, selector: "clr-timeline-step", inputs: { state: ["clrState", "state"] }, host: { properties: { "class.clr-timeline-step": "true", "attr.role": "\"listitem\"" } }, queries: [{ propertyName: "stepTitle", first: true, predicate: ClrTimelineStepTitle, descendants: true, read: ElementRef }], ngImport: i0, template: `
24544
24600
  <ng-content select="clr-timeline-step-header"></ng-content>
24545
24601
  <span class="clr-sr-only">{{ stepTitleText }}</span>
24546
24602
  <ng-container *ngIf="!isProcessing; else processing">
@@ -24584,7 +24640,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImpor
24584
24640
  <clr-spinner clrMedium [attr.aria-label]="iconAriaLabel"></clr-spinner>
24585
24641
  </ng-template>
24586
24642
  `,
24587
- host: { '[class.clr-timeline-step]': 'true' },
24643
+ host: { '[class.clr-timeline-step]': 'true', '[attr.role]': '"listitem"' },
24588
24644
  }]
24589
24645
  }], ctorParameters: function () { return [{ type: TimelineIconAttributeService }, { type: undefined, decorators: [{
24590
24646
  type: Inject,