Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes aria-activedescendants incorrect attribute in hierarchical grid #11220

Merged
merged 11 commits into from
Mar 24, 2022
40 changes: 24 additions & 16 deletions projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ export class IgxGridNavigationService {
const shift = event.shiftKey;
const ctrl = event.ctrlKey;
if (NAVIGATION_KEYS.has(key) && this.pendingNavigation) {
event.preventDefault(); return;
event.preventDefault();
return;
}

const type = this.isDataRow(this.activeNode.row) ? 'dataCell' :
Expand Down Expand Up @@ -132,7 +133,8 @@ export class IgxGridNavigationService {
public focusTbody(event) {
const gridRows = this.grid.verticalScrollContainer.totalItemCount ?? this.grid.dataView.length;
if (gridRows < 1) {
this.activeNode = null; return;
this.activeNode = null;
return;
}
if (!this.activeNode || !Object.keys(this.activeNode).length || this.activeNode.row < 0 || this.activeNode.row > gridRows - 1) {
const hasLastActiveNode = Object.keys(this.lastActiveNode).length;
Expand All @@ -144,10 +146,12 @@ export class IgxGridNavigationService {
this.grid.navigateTo(this.activeNode.row, this.activeNode.column, (obj) => {
obj.target?.activate(event);
this.grid.cdr.detectChanges();
} );
});
} else {
const range = { rowStart: this.activeNode.row, rowEnd: this.activeNode.row,
columnStart: this.activeNode.column, columnEnd: this.activeNode.column };
const range = {
rowStart: this.activeNode.row, rowEnd: this.activeNode.row,
columnStart: this.activeNode.column, columnEnd: this.activeNode.column
};
this.grid.selectRange(range);
this.grid.notifyChanges();
}
Expand All @@ -157,7 +161,7 @@ export class IgxGridNavigationService {
public focusFirstCell(header = true) {
if ((header || this.grid.dataView.length) && this.activeNode &&
(this.activeNode.row === -1 || this.activeNode.row === this.grid.dataView.length ||
(!header && !this.grid.hasSummarizedColumns))) {
(!header && !this.grid.hasSummarizedColumns))) {
return;
}
const shouldScrollIntoView = this.lastActiveNode && (header && this.lastActiveNode.row !== -1) ||
Expand Down Expand Up @@ -253,11 +257,11 @@ export class IgxGridNavigationService {
let curRow: any;

if (rowIndex < 0 || rowIndex > this.grid.dataView.length - 1) {
curRow = this.grid.dataView[rowIndex - this.grid.virtualizationState.startIndex];
if (!curRow){
curRow = this.grid.dataView[rowIndex - this.grid.virtualizationState.startIndex];
if (!curRow) {
return false;
}
}else {
} else {
curRow = this.grid.dataView[rowIndex];
}
return curRow && !this.grid.isGroupByRecord(curRow) && !this.grid.isDetailRecord(curRow)
Expand Down Expand Up @@ -495,7 +499,7 @@ export class IgxGridNavigationService {

protected forOfDir(): IgxForOfDirective<any> {
const forOfDir = this.grid.dataRowList.length > 0 ? this.grid.dataRowList.first.virtDirRow : this.grid.summariesRowList.length ?
this.grid.summariesRowList.first.virtDirRow : this.grid.headerContainer;
this.grid.summariesRowList.first.virtDirRow : this.grid.headerContainer;
return forOfDir as IgxForOfDirective<any>;
}

Expand Down Expand Up @@ -681,17 +685,21 @@ export class IgxGridNavigationService {
}
}

private firstVisibleNode(rowIndex?) {
private firstVisibleNode(rowIndex?) {
const colIndex = this.lastActiveNode.column !== undefined ? this.lastActiveNode.column :
this.grid.visibleColumns.sort((c1, c2) => c1.visibleIndex - c2.visibleIndex)
.find(c => this.isColumnFullyVisible(c.visibleIndex))?.visibleIndex;
.find(c => this.isColumnFullyVisible(c.visibleIndex))?.visibleIndex;
const column = this.grid.visibleColumns.find((col) => !col.columnLayout && col.visibleIndex === colIndex);
const rowInd = rowIndex ? rowIndex : this.grid.rowList.find(r => !this.shouldPerformVerticalScroll(r.index, colIndex))?.index;
const node = { row: rowInd ?? 0,
const node = {
row: rowInd ?? 0,
column: column?.visibleIndex ?? 0, level: column?.level ?? 0,
mchCache: column ? {level: column.level, visibleIndex: column.visibleIndex} : {} as ColumnGroupsCache,
layout: column && column.columnLayoutChild ? { rowStart: column.rowStart, colStart: column.colStart,
rowEnd: column.rowEnd, colEnd: column.colEnd, columnVisibleIndex: column.visibleIndex} : null };
mchCache: column ? { level: column.level, visibleIndex: column.visibleIndex } : {} as ColumnGroupsCache,
layout: column && column.columnLayoutChild ? {
rowStart: column.rowStart, colStart: column.colStart,
rowEnd: column.rowEnd, colEnd: column.colEnd, columnVisibleIndex: column.visibleIndex
} : null
};
return node;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { IgxGridNavigationService } from '../grid-navigation.service';
import { first } from 'rxjs/operators';
import { SUPPORTED_KEYS, NAVIGATION_KEYS } from '../../core/utils';
import { Injectable } from '@angular/core';
import { first } from 'rxjs/operators';
import { NAVIGATION_KEYS, SUPPORTED_KEYS } from '../../core/utils';
import { GridType, IPathSegment, RowType } from '../common/grid.interface';
import { IActiveNode, IgxGridNavigationService } from '../grid-navigation.service';

@Injectable()
export class IgxHierarchicalGridNavigationService extends IgxGridNavigationService {
Expand Down Expand Up @@ -301,8 +301,8 @@ export class IgxHierarchicalGridNavigationService extends IgxGridNavigationServi

private clearActivation() {
// clear if previous activation exists.
if (this.activeNode) {
this.activeNode.row = null;
if (this.activeNode && Object.keys(this.activeNode).length) {
this.activeNode = Object.assign({} as IActiveNode);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,30 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => {
expect(row1.expanded).toBe(false);
expect(row2.expanded).toBe(true);
});

it('should update aria-activeDescendants when navigating around', () => {
hierarchicalGrid.cellSelection = 'single';
expect(hierarchicalGrid.tbody.nativeElement.attributes['aria-activedescendant'].value).toEqual(hierarchicalGrid.id);

let cellElem = (hierarchicalGrid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[1];
UIInteractions.simulatePointerOverElementEvent('pointerdown', cellElem.nativeElement);
fixture.detectChanges();
expect(hierarchicalGrid.tbody.nativeElement.attributes['aria-activedescendant'].value).toEqual(`${hierarchicalGrid.id}_0_1`);

const row1 = hierarchicalGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;
UIInteractions.simulateClickAndSelectEvent(row1.expander);
fixture.detectChanges();

const childGrid = hierarchicalGrid.getChildGrids()[0];
expect(childGrid.tbody.nativeElement.attributes['aria-activedescendant'].value).toEqual(childGrid.id);

cellElem = (childGrid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[1];
UIInteractions.simulatePointerOverElementEvent('pointerdown', cellElem.nativeElement);
fixture.detectChanges();

expect(hierarchicalGrid.tbody.nativeElement.attributes['aria-activedescendant'].value).toEqual(hierarchicalGrid.id);
expect(childGrid.tbody.nativeElement.attributes['aria-activedescendant'].value).toEqual(`${childGrid.id}_0_1`);
});
});

describe('IgxHierarchicalGrid Row Islands #hGrid', () => {
Expand Down