@clr/angular 13.2.1 → 13.3.0

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.
@@ -13100,7 +13100,7 @@ ClrDatagridPlaceholder.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", v
13100
13100
  ClrDatagridPlaceholder.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.3", type: ClrDatagridPlaceholder, selector: "clr-dg-placeholder", host: { properties: { "class.datagrid-placeholder-container": "true" } }, ngImport: i0, template: `
13101
13101
  <div class="datagrid-placeholder" [class.datagrid-empty]="emptyDatagrid" role="row">
13102
13102
  <div class="datagrid-placeholder-image" *ngIf="emptyDatagrid"></div>
13103
- <span role="gridcell"><ng-content *ngIf="emptyDatagrid"></ng-content></span>
13103
+ <span role="gridcell" class="datagrid-placeholder-content"><ng-content *ngIf="emptyDatagrid"></ng-content></span>
13104
13104
  </div>
13105
13105
  `, isInline: true, directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
13106
13106
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: ClrDatagridPlaceholder, decorators: [{
@@ -13110,7 +13110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImpor
13110
13110
  template: `
13111
13111
  <div class="datagrid-placeholder" [class.datagrid-empty]="emptyDatagrid" role="row">
13112
13112
  <div class="datagrid-placeholder-image" *ngIf="emptyDatagrid"></div>
13113
- <span role="gridcell"><ng-content *ngIf="emptyDatagrid"></ng-content></span>
13113
+ <span role="gridcell" class="datagrid-placeholder-content"><ng-content *ngIf="emptyDatagrid"></ng-content></span>
13114
13114
  </div>
13115
13115
  `,
13116
13116
  host: { '[class.datagrid-placeholder-container]': 'true' },
@@ -14258,13 +14258,181 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImpor
14258
14258
  type: Injectable
14259
14259
  }] });
14260
14260
 
14261
+ /*
14262
+ * Copyright (c) 2016-2022 VMware, Inc. All Rights Reserved.
14263
+ * This software is released under MIT license.
14264
+ * The full license information can be found in LICENSE in the root directory of this project.
14265
+ */
14266
+ function getTabableItems(el) {
14267
+ const tabableSelector = [
14268
+ 'a[href]',
14269
+ 'area[href]',
14270
+ 'input:not([disabled])',
14271
+ 'button:not([disabled])',
14272
+ 'select:not([disabled])',
14273
+ 'textarea:not([disabled])',
14274
+ 'iframe',
14275
+ 'object',
14276
+ 'embed',
14277
+ '*[tabindex]',
14278
+ '*[contenteditable=true]',
14279
+ '[role=button]:not([disabled])',
14280
+ ].join(',');
14281
+ return Array.from(el.querySelectorAll(tabableSelector));
14282
+ }
14283
+ class KeyNavigationGridController {
14284
+ constructor(zone) {
14285
+ this.zone = zone;
14286
+ this.listenersAdded = false;
14287
+ this.destroy$ = new Subject();
14288
+ this.config = {
14289
+ keyGridRows: '[role=row]:not(.datagrid-placeholder)',
14290
+ keyGridCells: '[role=gridcell]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), [role=columnheader]:not(.datagrid-hidden-column):not(.datagrid-placeholder-content), .datagrid-detail-caret',
14291
+ keyGrid: '[role=grid]',
14292
+ };
14293
+ }
14294
+ get grid() {
14295
+ return this.host?.querySelector(this.config.keyGrid);
14296
+ }
14297
+ get rows() {
14298
+ return this.host?.querySelectorAll(this.config.keyGridRows);
14299
+ }
14300
+ get cells() {
14301
+ return this.host?.querySelectorAll(this.config.keyGridCells);
14302
+ }
14303
+ ngOnDestroy() {
14304
+ this.destroy$.next();
14305
+ this.destroy$.complete();
14306
+ }
14307
+ addListeners() {
14308
+ if (this.listenersAdded) {
14309
+ return;
14310
+ }
14311
+ this.zone.runOutsideAngular(() => {
14312
+ fromEvent(this.grid, 'mousedown')
14313
+ .pipe(takeUntil(this.destroy$))
14314
+ .subscribe((e) => {
14315
+ // 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
14316
+ if (e.buttons === 1 && !e.ctrlKey) {
14317
+ const activeCell = this.cells
14318
+ ? Array.from(this.cells).find(c => c === e.target || c === e.target.closest(this.config.keyGridCells))
14319
+ : null;
14320
+ if (activeCell) {
14321
+ this.setActiveCell(activeCell);
14322
+ }
14323
+ }
14324
+ });
14325
+ fromEvent(this.grid, 'keydown')
14326
+ .pipe(takeUntil(this.destroy$))
14327
+ .subscribe((e) => {
14328
+ // Skip column resize events
14329
+ if (e.target.classList.contains('drag-handle') &&
14330
+ (e.code === 'ArrowLeft' || e.code === 'ArrowRight')) {
14331
+ return;
14332
+ }
14333
+ if (e.code === 'ArrowUp' ||
14334
+ e.code === 'ArrowDown' ||
14335
+ e.code === 'ArrowLeft' ||
14336
+ e.code === 'ArrowRight' ||
14337
+ e.code === 'End' ||
14338
+ e.code === 'Home' ||
14339
+ e.code === 'PageUp' ||
14340
+ e.code === 'PageDown') {
14341
+ const { x, y } = this.getNextItemCoordinate(e);
14342
+ const activeItem = this.rows
14343
+ ? Array.from(this.rows[y].querySelectorAll(this.config.keyGridCells))[x]
14344
+ : null;
14345
+ if (activeItem) {
14346
+ this.setActiveCell(activeItem);
14347
+ }
14348
+ e.preventDefault();
14349
+ }
14350
+ });
14351
+ });
14352
+ this.listenersAdded = true;
14353
+ }
14354
+ initializeKeyGrid(host) {
14355
+ this.host = host;
14356
+ this.addListeners();
14357
+ this.resetKeyGrid();
14358
+ }
14359
+ resetKeyGrid() {
14360
+ this.cells?.forEach((i) => i.setAttribute('tabindex', '-1'));
14361
+ const firstCell = this.cells ? this.cells[0] : null;
14362
+ firstCell?.setAttribute('tabindex', '0');
14363
+ }
14364
+ setActiveCell(activeCell) {
14365
+ const prior = this.cells ? Array.from(this.cells).find(c => c.getAttribute('tabindex') === '0') : null;
14366
+ if (prior) {
14367
+ prior.setAttribute('tabindex', '-1');
14368
+ }
14369
+ activeCell.setAttribute('tabindex', '0');
14370
+ const items = getTabableItems(activeCell);
14371
+ const item = activeCell.getAttribute('role') !== 'columnheader' && items[0] ? items[0] : activeCell;
14372
+ item.focus();
14373
+ }
14374
+ getNextItemCoordinate(e) {
14375
+ let currentCell = this.cells ? Array.from(this.cells).find(i => i.getAttribute('tabindex') === '0') : null;
14376
+ if (e.code === 'Tab') {
14377
+ currentCell = document.activeElement;
14378
+ }
14379
+ const currentRow = this.rows && currentCell ? Array.from(this.rows).find(r => r.contains(currentCell)) : null;
14380
+ const numOfRows = this.rows ? this.rows.length - 1 : 0;
14381
+ const numOfColumns = this.cells ? this.cells.length / this.rows.length - 1 : 0;
14382
+ let x = currentRow && currentCell
14383
+ ? Array.from(currentRow.querySelectorAll(this.config.keyGridCells)).indexOf(currentCell)
14384
+ : 0;
14385
+ let y = currentRow && currentCell && this.rows ? Array.from(this.rows).indexOf(currentRow) : 0;
14386
+ const dir = this.host.dir;
14387
+ const inlineStart = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
14388
+ const inlineEnd = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
14389
+ const itemsPerPage = Math.floor(this.host?.querySelector('.datagrid').clientHeight / this.rows[0].clientHeight) - 1 || 0;
14390
+ if (e.code === 'ArrowUp' && y !== 0) {
14391
+ y = y - 1;
14392
+ }
14393
+ else if (e.code === 'ArrowDown' && y < numOfRows) {
14394
+ y = y + 1;
14395
+ }
14396
+ else if (e.code === inlineStart && x !== 0) {
14397
+ x = x - 1;
14398
+ }
14399
+ else if (e.code === inlineEnd && x < numOfColumns) {
14400
+ x = x + 1;
14401
+ }
14402
+ else if (e.code === 'End') {
14403
+ x = numOfColumns;
14404
+ if (e.ctrlKey) {
14405
+ y = numOfRows;
14406
+ }
14407
+ }
14408
+ else if (e.code === 'Home') {
14409
+ x = 0;
14410
+ if (e.ctrlKey) {
14411
+ y = 0;
14412
+ }
14413
+ }
14414
+ else if (e.code === 'PageUp') {
14415
+ y = y - itemsPerPage > 0 ? y - itemsPerPage : 0;
14416
+ }
14417
+ else if (e.code === 'PageDown') {
14418
+ y = y + itemsPerPage < numOfRows ? y + itemsPerPage : numOfRows;
14419
+ }
14420
+ return { x, y };
14421
+ }
14422
+ }
14423
+ KeyNavigationGridController.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: KeyNavigationGridController, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
14424
+ KeyNavigationGridController.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: KeyNavigationGridController });
14425
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: KeyNavigationGridController, decorators: [{
14426
+ type: Injectable
14427
+ }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
14428
+
14261
14429
  /*
14262
14430
  * Copyright (c) 2016-2022 VMware, Inc. All Rights Reserved.
14263
14431
  * This software is released under MIT license.
14264
14432
  * The full license information can be found in LICENSE in the root directory of this project.
14265
14433
  */
14266
14434
  class ClrDatagrid {
14267
- constructor(organizer, items, expandableRows, selection, rowActionService, stateProvider, displayMode, renderer, detailService, datagridId, el, page, commonStrings) {
14435
+ constructor(organizer, items, expandableRows, selection, rowActionService, stateProvider, displayMode, renderer, detailService, datagridId, el, page, commonStrings, columnsService, keyNavigation) {
14268
14436
  this.organizer = organizer;
14269
14437
  this.items = items;
14270
14438
  this.expandableRows = expandableRows;
@@ -14277,6 +14445,8 @@ class ClrDatagrid {
14277
14445
  this.el = el;
14278
14446
  this.page = page;
14279
14447
  this.commonStrings = commonStrings;
14448
+ this.columnsService = columnsService;
14449
+ this.keyNavigation = keyNavigation;
14280
14450
  /* reference to the enum so that template can access */
14281
14451
  this.SELECTION_TYPE = SelectionType;
14282
14452
  /**
@@ -14402,6 +14572,7 @@ class ClrDatagrid {
14402
14572
  * Our setup happens in the view of some of our components, so we wait for it to be done before starting
14403
14573
  */
14404
14574
  ngAfterViewInit() {
14575
+ this.keyNavigation.initializeKeyGrid(this.el.nativeElement);
14405
14576
  // TODO: determine if we can get rid of provider wiring in view init so that subscriptions can be done earlier
14406
14577
  this.refresh.emit(this.stateProvider.state);
14407
14578
  this._subscriptions.push(this.stateProvider.change.subscribe(state => this.refresh.emit(state)), this.selection.change.subscribe(s => {
@@ -14411,11 +14582,16 @@ class ClrDatagrid {
14411
14582
  else if (this.selection.selectionType === SelectionType.Multi) {
14412
14583
  this.selectedChanged.emit(s);
14413
14584
  }
14414
- }), this.page.change.subscribe(() => {
14585
+ }),
14586
+ // Reinitialize arrow key navigation on page changes
14587
+ this.page.change.subscribe(() => {
14588
+ this.keyNavigation.resetKeyGrid();
14415
14589
  if (!this.clrDgDisablePageFocus) {
14416
14590
  this.datagridTable.nativeElement.focus();
14417
14591
  }
14418
14592
  }),
14593
+ // Reinitialize arrow key navigation on hide/unhide columns
14594
+ combineLatest(this.columnsService.columns).subscribe(() => this.keyNavigation?.resetKeyGrid()),
14419
14595
  // A subscription that listens for displayMode changes on the datagrid
14420
14596
  this.displayMode.view.subscribe(viewChange => {
14421
14597
  // Remove any projected columns from the projectedDisplayColumns container
@@ -14463,7 +14639,7 @@ class ClrDatagrid {
14463
14639
  this.organizer.resize();
14464
14640
  }
14465
14641
  }
14466
- ClrDatagrid.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: ClrDatagrid, deps: [{ token: DatagridRenderOrganizer }, { token: Items }, { token: ExpandableRowsCount }, { token: Selection }, { token: RowActionService }, { token: StateProvider }, { token: DisplayModeService }, { token: i0.Renderer2 }, { token: DetailService }, { token: UNIQUE_ID }, { token: i0.ElementRef }, { token: Page }, { token: ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
14642
+ ClrDatagrid.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: ClrDatagrid, deps: [{ token: DatagridRenderOrganizer }, { token: Items }, { token: ExpandableRowsCount }, { token: Selection }, { token: RowActionService }, { token: StateProvider }, { token: DisplayModeService }, { token: i0.Renderer2 }, { token: DetailService }, { token: UNIQUE_ID }, { token: i0.ElementRef }, { token: Page }, { token: ClrCommonStringsService }, { token: ColumnsService }, { token: KeyNavigationGridController }], target: i0.ɵɵFactoryTarget.Component });
14467
14643
  ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.3", type: ClrDatagrid, selector: "clr-datagrid", inputs: { loading: ["clrDgLoading", "loading"], selected: ["clrDgSelected", "selected"], singleSelected: ["clrDgSingleSelected", "singleSelected"], clrDgSingleSelectionAriaLabel: "clrDgSingleSelectionAriaLabel", clrDgSingleActionableAriaLabel: "clrDgSingleActionableAriaLabel", clrDetailExpandableAriaLabel: "clrDetailExpandableAriaLabel", clrDgDisablePageFocus: "clrDgDisablePageFocus", clrDgPreserveSelection: "clrDgPreserveSelection", rowSelectionMode: ["clrDgRowSelection", "rowSelectionMode"] }, outputs: { refresh: "clrDgRefresh", selectedChanged: "clrDgSelectedChange", singleSelectedChanged: "clrDgSingleSelectedChange" }, host: { properties: { "class.datagrid-host": "true", "class.datagrid-detail-open": "detailService.isOpen" } }, providers: [
14468
14644
  Selection,
14469
14645
  Sort,
@@ -14480,7 +14656,8 @@ ClrDatagrid.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "
14480
14656
  TableSizeService,
14481
14657
  ColumnsService,
14482
14658
  DisplayModeService,
14483
- ], 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: "scrollableColumns", first: true, predicate: ["scrollableColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "datagridTable", first: true, predicate: ["datagridTable"], descendants: true, read: ElementRef }, { 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-2021 VMware, Inc. All Rights Reserved.\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 >\n <div class=\"clr-checkbox-wrapper\">\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\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 [attr.aria-label]=\"clrDgSingleSelectionAriaLabel\"\n >\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 [attr.aria-label]=\"clrDgSingleActionableAriaLabel\"\n >\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 [attr.aria-label]=\"clrDetailExpandableAriaLabel\"\n >\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 <ng-container #displayedRows></ng-container>\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 <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", components: [{ type: ClrDatagridPlaceholder, selector: "clr-dg-placeholder" }, { type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: ClrLabel, selector: "label", inputs: ["for"] }] });
14659
+ KeyNavigationGridController,
14660
+ ], 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: "scrollableColumns", first: true, predicate: ["scrollableColumns"], descendants: true, read: ViewContainerRef }, { propertyName: "datagridTable", first: true, predicate: ["datagridTable"], descendants: true, read: ElementRef }, { 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-2021 VMware, Inc. All Rights Reserved.\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 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 [attr.aria-label]=\"clrDgSingleSelectionAriaLabel\"\n >\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 [attr.aria-label]=\"clrDgSingleActionableAriaLabel\"\n >\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 [attr.aria-label]=\"clrDetailExpandableAriaLabel\"\n >\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 <ng-container #displayedRows></ng-container>\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 <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", components: [{ type: ClrDatagridPlaceholder, selector: "clr-dg-placeholder" }, { type: ClrSpinner, selector: "clr-spinner", inputs: ["clrInline", "clrInverse", "clrSmall", "clrMedium"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: ClrLabel, selector: "label", inputs: ["for"] }] });
14484
14661
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: ClrDatagrid, decorators: [{
14485
14662
  type: Component,
14486
14663
  args: [{ selector: 'clr-datagrid', providers: [
@@ -14499,14 +14676,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImpor
14499
14676
  TableSizeService,
14500
14677
  ColumnsService,
14501
14678
  DisplayModeService,
14679
+ KeyNavigationGridController,
14502
14680
  ], host: {
14503
14681
  '[class.datagrid-host]': 'true',
14504
14682
  '[class.datagrid-detail-open]': 'detailService.isOpen',
14505
- }, template: "<!--\n ~ Copyright (c) 2016-2021 VMware, Inc. All Rights Reserved.\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 >\n <div class=\"clr-checkbox-wrapper\">\n <input\n type=\"checkbox\"\n [id]=\"selectAllId\"\n [(ngModel)]=\"allSelected\"\n [attr.aria-label]=\"commonStrings.keys.selectAll\"\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 [attr.aria-label]=\"clrDgSingleSelectionAriaLabel\"\n >\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 [attr.aria-label]=\"clrDgSingleActionableAriaLabel\"\n >\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 [attr.aria-label]=\"clrDetailExpandableAriaLabel\"\n >\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 <ng-container #displayedRows></ng-container>\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 <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" }]
14683
+ }, template: "<!--\n ~ Copyright (c) 2016-2021 VMware, Inc. All Rights Reserved.\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 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 [attr.aria-label]=\"clrDgSingleSelectionAriaLabel\"\n >\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 [attr.aria-label]=\"clrDgSingleActionableAriaLabel\"\n >\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 [attr.aria-label]=\"clrDetailExpandableAriaLabel\"\n >\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 <ng-container #displayedRows></ng-container>\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 <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" }]
14506
14684
  }], 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: [{
14507
14685
  type: Inject,
14508
14686
  args: [UNIQUE_ID]
14509
- }] }, { type: i0.ElementRef }, { type: Page }, { type: ClrCommonStringsService }]; }, propDecorators: { loading: [{
14687
+ }] }, { type: i0.ElementRef }, { type: Page }, { type: ClrCommonStringsService }, { type: ColumnsService }, { type: KeyNavigationGridController }]; }, propDecorators: { loading: [{
14510
14688
  type: Input,
14511
14689
  args: ['clrDgLoading']
14512
14690
  }], refresh: [{