fix button column accessibility issue (#10307)

* fix accessibility issue

* comment
This commit is contained in:
Alan Ren
2020-05-08 14:24:03 -07:00
committed by GitHub
parent ea84e60fa0
commit 3a70bea70d
2 changed files with 19 additions and 7 deletions

View File

@@ -176,9 +176,8 @@
align-items: center; align-items: center;
} }
.slick-icon-cell,
.slick-button-cell { .slick-button-cell {
padding: 0px !important; padding: 5px !important;
} }
.slick-button-cell-content { .slick-button-cell-content {

View File

@@ -40,7 +40,8 @@ export class ButtonColumn<T extends Slick.SlickData> implements Slick.Plugin<T>
}, },
width: options.width, width: options.width,
selectable: false, selectable: false,
iconCssClassField: options.iconCssClass iconCssClassField: options.iconCssClass,
cssClass: 'slick-button-cell'
}; };
} }
@@ -48,14 +49,23 @@ export class ButtonColumn<T extends Slick.SlickData> implements Slick.Plugin<T>
this._grid = grid; this._grid = grid;
this._handler.subscribe(grid.onClick, (e: DOMEvent, args: Slick.OnClickEventArgs<T>) => this.handleClick(args)); this._handler.subscribe(grid.onClick, (e: DOMEvent, args: Slick.OnClickEventArgs<T>) => this.handleClick(args));
this._handler.subscribe(grid.onKeyDown, (e: DOMEvent, args: Slick.OnKeyDownEventArgs<T>) => this.handleKeyboardEvent(e as KeyboardEvent, args)); this._handler.subscribe(grid.onKeyDown, (e: DOMEvent, args: Slick.OnKeyDownEventArgs<T>) => this.handleKeyboardEvent(e as KeyboardEvent, args));
this._handler.subscribe(grid.onActiveCellChanged, (e: DOMEvent, args: Slick.OnActiveCellChangedEventArgs<T>) => { this.handleActiveCellChanged(args); });
} }
public destroy(): void { public destroy(): void {
this._handler.unsubscribeAll(); this._handler.unsubscribeAll();
} }
private handleActiveCellChanged(args: Slick.OnActiveCellChangedEventArgs<T>): void {
if (this.isCurrentColumn(args.cell)) {
const cellElement = this._grid.getActiveCellNode();
const button = cellElement.children[0] as HTMLButtonElement;
button.focus();
}
}
private handleClick(args: Slick.OnClickEventArgs<T>): void { private handleClick(args: Slick.OnClickEventArgs<T>): void {
if (this.shouldFireClickEvent(args.cell)) { if (this.isCurrentColumn(args.cell)) {
this._grid.setActiveCell(args.row, args.cell); this._grid.setActiveCell(args.row, args.cell);
this.fireClickEvent(); this.fireClickEvent();
} }
@@ -63,7 +73,7 @@ export class ButtonColumn<T extends Slick.SlickData> implements Slick.Plugin<T>
private handleKeyboardEvent(e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>): void { private handleKeyboardEvent(e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>): void {
let event = new StandardKeyboardEvent(e); let event = new StandardKeyboardEvent(e);
if ((event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) && this.shouldFireClickEvent(args.cell)) { if ((event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) && this.isCurrentColumn(args.cell)) {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
this.fireClickEvent(); this.fireClickEvent();
@@ -88,12 +98,15 @@ export class ButtonColumn<T extends Slick.SlickData> implements Slick.Plugin<T>
} }
} }
private shouldFireClickEvent(columnIndex: number): boolean { private isCurrentColumn(columnIndex: number): boolean {
return this._grid.getColumns()[columnIndex].id === this.definition.id; return this._grid.getColumns()[columnIndex].id === this.definition.id;
} }
private formatter(row: number, cell: number, value: any, columnDef: Slick.Column<T>, dataContext: T): string { private formatter(row: number, cell: number, value: any, columnDef: Slick.Column<T>, dataContext: T): string {
const buttonColumn = columnDef as ButtonColumnDefinition<T>; const buttonColumn = columnDef as ButtonColumnDefinition<T>;
return `<div class="codicon icon slick-button-cell-content ${buttonColumn.iconCssClassField}" aria-label="${this.options.title}"></div>`;
// tabindex=-1 means it is only focusable programatically, when the button column cell becomes active, we will set to focus to the button inside it, the tab navigation experience is smooth.
// Otherwise, if we set tabindex to 0, the focus will go to the button first and then the first cell of the table.
return `<button tabindex=-1 class="codicon icon slick-button-cell-content ${buttonColumn.iconCssClassField}" aria-label="${this.options.title}"></button>`;
} }
} }