table keyboard focus (#17903)

* fix table keyboard focus issue

* add comments

* pr comment

* pr comments
This commit is contained in:
Alan Ren
2021-12-13 13:00:27 -08:00
committed by GitHub
parent 44301087c1
commit 177663cc29

View File

@@ -80,18 +80,20 @@ export class Table<T extends Slick.SlickData> extends Widget implements IDisposa
this._container = document.createElement('div'); this._container = document.createElement('div');
this._container.className = 'monaco-table'; this._container.className = 'monaco-table';
this._register(DOM.addDisposableListener(this._container, DOM.EventType.FOCUS, (e: FocusEvent) => { this._register(DOM.addDisposableListener(this._container, DOM.EventType.FOCUS, (e: FocusEvent) => {
// the focus redirection should only happen when the event target is the container (using keyboard navigation) // Focus redirection should only happen when the event target is the container (using keyboard navigation)
if (e.target && this._container === e.target && !this.grid.getActiveCell() && this._data.getLength() > 0) { if (e.target && this._container === e.target && this._data.getLength() > 0) {
// When the table receives focus and there are currently no active cell, the focus should go to the first focusable cell. let cellToFocus = this.grid.getActiveCell();
let cellToFocus = undefined; if (!cellToFocus) {
for (let col = 0; col < this.columns.length; col++) { // When the table receives focus and there are currently no active cell, the focus should go to the first focusable cell.
// some cells are not keyboard focusable (e.g. row number column), we need to find the first focusable cell. for (let col = 0; col < this.columns.length; col++) {
if (this.grid.canCellBeActive(0, col)) { // some cells are not keyboard focusable (e.g. row number column), we need to find the first focusable cell.
cellToFocus = { if (this.grid.canCellBeActive(0, col)) {
row: 0, cellToFocus = {
cell: col row: 0,
}; cell: col
break; };
break;
}
} }
} }
if (cellToFocus) { if (cellToFocus) {
@@ -140,11 +142,14 @@ export class Table<T extends Slick.SlickData> extends Widget implements IDisposa
this.mapMouseEvent(this._grid.onDblClick, this._onDoubleClick); this.mapMouseEvent(this._grid.onDblClick, this._onDoubleClick);
this._grid.onColumnsResized.subscribe(() => this._onColumnResize.fire()); this._grid.onColumnsResized.subscribe(() => this._onColumnResize.fire());
this._grid.onRendered.subscribe(() => { this._grid.onRendered.subscribe(() => {
if (!this._grid.getActiveCell()) { // When there are data present and no cells are keyboard focusable, the container should be set to keyboard focusable to
this._container.tabIndex = this._data.getLength() > 0 ? 0 : -1; // leverage the focus redirection logic.
} this._container.tabIndex = this._container.querySelector('[tabindex = "0"]') || this._data.getLength() === 0 ? -1 : 0;
}); });
this._grid.onActiveCellChanged.subscribe((e, data) => { this._grid.onActiveCellChanged.subscribe((e, data) => {
// When the active cell is changed, a cell will become focusable and we can make the container not focusable by user.
// later when the grid is rerendered (e.g. view switching), the active cell information is kept but the cell will become not keyboard focusable (tabindex changed from 0 to -1).
// we need to check and reset the tabIndex of the container in the onRendered handler.
this._container.tabIndex = -1; this._container.tabIndex = -1;
}); });
} }