mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
[ACS-10205]: Extends DataTableAdapter interface to handle focus for accessibility (#11506)
* [ACS-10205]: updates base DataTableAdapter class with optional props * [ACS-10205]: updates ShareDataTableAdapter with new props for focus handling * [ACS-10205]: bind new focus props to template * [ACS-10205]: uts update * [ACS-10205]: uts refactor * [ACS-10205]: fixes circullar deps
This commit is contained in:
@@ -493,4 +493,16 @@ describe('ShareDataTableAdapter', () => {
|
||||
expect(adapter.getRowByNodeId('fake-node-id-2')).toEqual(fakeShareDataRows[1]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should initialize with allowFocusOnRows as true by default', () => {
|
||||
const adapter = new ShareDataTableAdapter(thumbnailService, contentService, null);
|
||||
expect(adapter.allowFocusOnRows).toBe(true);
|
||||
});
|
||||
|
||||
it('should set allowFocusOnRows value', () => {
|
||||
const adapter = new ShareDataTableAdapter(thumbnailService, contentService, null);
|
||||
expect(adapter.allowFocusOnRows).toBe(true);
|
||||
adapter.setAllowFocusOnTableRows(false);
|
||||
expect(adapter.allowFocusOnRows).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -34,10 +34,11 @@ export class ShareDataTableAdapter implements DataTableAdapter {
|
||||
private filter: RowFilter;
|
||||
private imageResolver: any;
|
||||
|
||||
thumbnails: boolean = false;
|
||||
thumbnails = false;
|
||||
permissionsStyle: PermissionStyleModel[];
|
||||
selectedRow: DataRow;
|
||||
allowDropFiles: boolean;
|
||||
allowFocusOnRows = true;
|
||||
|
||||
set sortingMode(value: string) {
|
||||
let newValue = (value || 'client').toLowerCase();
|
||||
@@ -196,6 +197,10 @@ export class ShareDataTableAdapter implements DataTableAdapter {
|
||||
this.imageResolver = resolver;
|
||||
}
|
||||
|
||||
setAllowFocusOnTableRows(allow: boolean) {
|
||||
this.allowFocusOnRows = allow;
|
||||
}
|
||||
|
||||
private getFolderIcon(node: any) {
|
||||
if (this.isSmartFolder(node)) {
|
||||
return this.thumbnailService.getMimeTypeIcon('smartFolder');
|
||||
|
||||
@@ -206,7 +206,9 @@
|
||||
[ngClass]="getRowStyle(row)"
|
||||
[class.adf-datatable-row__dragging]="isDraggingRow"
|
||||
[attr.data-automation-id]="'datatable-row-' + idx"
|
||||
(contextmenu)="markRowAsContextMenuSource(row)">
|
||||
(contextmenu)="markRowAsContextMenuSource(row)"
|
||||
[disabled]="!(data.allowFocusOnRows ?? true)"
|
||||
>
|
||||
<!-- Drag button -->
|
||||
<div *ngIf="enableDragRows"
|
||||
role="gridcell"
|
||||
@@ -269,7 +271,7 @@
|
||||
[attr.aria-selected]="row.isSelected"
|
||||
[attr.aria-label]="col.title ? (col.title | translate) : null"
|
||||
(click)="onRowClick(row, $event)"
|
||||
tabindex="0"
|
||||
[attr.tabindex]="col.focus ? 0 : null"
|
||||
(keydown.enter)="onEnterKeyPressed(row, $any($event))"
|
||||
[adf-context-menu]="getContextMenuActions(row, col)"
|
||||
[adf-context-menu-enabled]="contextMenu"
|
||||
|
||||
@@ -1752,38 +1752,76 @@ describe('Accessibility', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove cell focus when [focus] is set to false', () => {
|
||||
dataTable.showHeader = ShowHeaderMode.Never;
|
||||
const dataRows = [{ name: 'name1' }];
|
||||
describe('DataTable row focus management', () => {
|
||||
const testFocus = (focus: boolean, selector: string, expectedTabindex: string | null) => {
|
||||
dataTable.showHeader = ShowHeaderMode.Never;
|
||||
const dataRows = [{ name: 'name1' }];
|
||||
|
||||
dataTable.data = new ObjectDataTableAdapter([], [new ObjectDataColumn({ key: 'name', template: columnCustomTemplate, focus: false })]);
|
||||
dataTable.data = new ObjectDataTableAdapter([], [new ObjectDataColumn({ key: 'name', template: columnCustomTemplate, focus })]);
|
||||
|
||||
dataTable.ngOnChanges({
|
||||
rows: new SimpleChange(null, dataRows, false)
|
||||
dataTable.ngOnChanges({
|
||||
rows: new SimpleChange(null, dataRows, false)
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
dataTable.ngAfterViewInit();
|
||||
|
||||
const element = testingUtils.getByCSS(selector);
|
||||
expect(element?.nativeElement.getAttribute('tabindex')).toEqual(expectedTabindex);
|
||||
};
|
||||
|
||||
const cellaValSelector = '.adf-datatable-row[data-automation-id="datatable-row-0"] .adf-cell-value';
|
||||
const cellWrapperSelector = '.adf-datatable-cell';
|
||||
|
||||
it('should remove cell focus when [focus] is set to false', () => {
|
||||
testFocus(false, cellaValSelector, null);
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
dataTable.ngAfterViewInit();
|
||||
it('should allow element focus when [focus] is set to true', () => {
|
||||
testFocus(true, cellaValSelector, '0');
|
||||
});
|
||||
|
||||
const cell = testingUtils.getByCSS('.adf-datatable-row[data-automation-id="datatable-row-0"] .adf-cell-value');
|
||||
expect(cell?.nativeElement.getAttribute('tabindex')).toBe(null);
|
||||
it('should remove col focus when [focus] is set to false', () => {
|
||||
testFocus(false, cellWrapperSelector, null);
|
||||
});
|
||||
|
||||
it('should allow col focus when [focus] is set to true', () => {
|
||||
testFocus(true, cellWrapperSelector, '0');
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow element focus when [focus] is set to true', () => {
|
||||
dataTable.showHeader = ShowHeaderMode.Never;
|
||||
const dataRows = [{ name: 'name1' }];
|
||||
describe('ShareDatatable adapter allowFocusOnRows', () => {
|
||||
class ShareAdapterMock extends ObjectDataTableAdapter {
|
||||
public allowFocusOnRows = true;
|
||||
|
||||
dataTable.data = new ObjectDataTableAdapter([], [new ObjectDataColumn({ key: 'name', template: columnCustomTemplate, focus: true })]);
|
||||
constructor(data: any[], schema: DataColumn[]) {
|
||||
super(data, schema);
|
||||
}
|
||||
|
||||
dataTable.ngOnChanges({
|
||||
rows: new SimpleChange(null, dataRows, false)
|
||||
setAllowFocusOnTableRows(allow: boolean) {
|
||||
this.allowFocusOnRows = allow;
|
||||
}
|
||||
}
|
||||
const testAllowFocusOnRows = (allowFocus: boolean, expectedTabindex: string | null) => {
|
||||
const fakeDataRows = [new FakeDataRow(), new FakeDataRow()];
|
||||
|
||||
const adapter = new ShareAdapterMock([], []);
|
||||
adapter.setRows(fakeDataRows);
|
||||
adapter.setAllowFocusOnTableRows(allowFocus);
|
||||
dataTable.data = adapter;
|
||||
fixture.detectChanges();
|
||||
const rowElements = testingUtils.getAllByCSS('.adf-datatable-body adf-datatable-row');
|
||||
expect(rowElements.length).toBeGreaterThan(0);
|
||||
expect(rowElements.every((row) => row.nativeElement.getAttribute('tabindex') === expectedTabindex)).toBeTrue();
|
||||
};
|
||||
|
||||
it('should set tabindex to null (disabled === true) on datatable-body rows when allowFocusOnRows is set to false in ShareDatatable adapter', () => {
|
||||
testAllowFocusOnRows(false, null);
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
dataTable.ngAfterViewInit();
|
||||
|
||||
const cell = testingUtils.getByCSS('.adf-datatable-row[data-automation-id="datatable-row-0"] .adf-cell-value');
|
||||
expect(cell?.nativeElement.getAttribute('tabindex')).toBe('0');
|
||||
it('should set tabindex to 0 (disabled === false) on datatable-body rows when allowFocusOnRows is set to true in ShareDatatable adapter (default case)', () => {
|
||||
testAllowFocusOnRows(true, '0');
|
||||
});
|
||||
});
|
||||
|
||||
it('should create focus trap on main menu open', () => {
|
||||
|
||||
@@ -22,6 +22,7 @@ import { Subject } from 'rxjs';
|
||||
|
||||
export interface DataTableAdapter {
|
||||
rowsChanged?: Subject<Array<DataRow>>;
|
||||
allowFocusOnRows?: boolean;
|
||||
|
||||
selectedRow: DataRow;
|
||||
getRows(): Array<DataRow>;
|
||||
@@ -33,4 +34,5 @@ export interface DataTableAdapter {
|
||||
getSorting(): DataSorting;
|
||||
setSorting(sorting: DataSorting): void;
|
||||
sort(key?: string, direction?: string): void;
|
||||
setAllowFocusOnTableRows?(allow: boolean): void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user