vpat 48: announce selection for default virtualized table (#4391)

* vpat 48: announce selection for default virt table

For simpler virtualized tables
(e.g. style manager in Zotero_Preferences.Cite), the table
does not get re-rendered when selection changes, so
aria-activedescendant does not get updated in render().

- a single function to update aria-activedescendant of the table
- call it in _updateTree of the tree selection because _onSelection
is not called the very first time a table is rendered. In that case, after
restart, collectionTree would have a selected row but no aria-activedescendant
- remove this.forceUpdate() from selection handlers of itemTree and
collectionTree because judging by the coment it's main purpose was to set
aria-activedescendant through render()
- set aria-activedescendant in _onSelection handler
of virtualized table. 
- construct and set aria-label for rows build via
makeRowRenderer of VirtualizedTable so that is is
announced when the row is selected.
This commit is contained in:
abaevbog 2024-07-17 00:34:16 -07:00 committed by GitHub
parent a46f1bcbbb
commit 40fd5efe05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 17 additions and 10 deletions

View file

@ -220,8 +220,6 @@ var CollectionTree = class CollectionTree extends LibraryTree {
}
}
}
// Update aria-activedescendant on the tree
this.forceUpdate();
if (shouldDebounce) {
this._onSelectionChangeDebounced();
}

View file

@ -256,6 +256,7 @@ class TreeSelection {
_updateTree(shouldDebounce) {
if (!this.selectEventsSuppressed && this._tree.props.onSelectionChange) {
this._tree.props.onSelectionChange(this, shouldDebounce);
this._tree._setAriaAciveDescendant();
}
}
@ -1281,12 +1282,6 @@ class VirtualizedTable extends React.Component {
if (this.props.role == 'treegrid') {
props['aria-readonly'] = true;
}
if (this.selection.count > 0) {
const elem = this._jsWindow && this._jsWindow.getElementByIndex(this.selection.focused);
if (elem) {
props['aria-activedescendant'] = elem.id;
}
}
let jsWindowProps = {
id: this._jsWindowID,
className: "virtualized-table-body",
@ -1434,6 +1429,15 @@ class VirtualizedTable extends React.Component {
this._columns = new Columns(this);
await new Promise((resolve) => {this.forceUpdate(resolve)});
}
// Set aria-activedescendant on table container
_setAriaAciveDescendant() {
if (!this.selection.focused) return;
let selected = this._jsWindow?.getElementByIndex(this.selection.focused);
if (selected) {
selected.closest(".virtualized-table").setAttribute("aria-activedescendant", selected.id);
}
}
}
/**
@ -1771,6 +1775,7 @@ function makeRowRenderer(getRowData) {
div.classList.toggle('selected', selection.isSelected(index));
div.classList.toggle('focused', selection.focused == index);
const rowData = getRowData(index);
let ariaLabel = "";
if (columns.length) {
for (let column of columns) {
@ -1782,12 +1787,18 @@ function makeRowRenderer(getRowData) {
else {
div.appendChild(renderCell(index, rowData[column.dataKey], column));
}
let columnName = column.label;
if (column.label in Zotero.Intl.strings) {
columnName = Zotero.getString(column.label);
}
ariaLabel += `${columnName}: ${rowData[column.dataKey]} `;
}
}
else {
div.appendChild(renderCell(index, rowData));
}
div.setAttribute("aria-label", ariaLabel);
return div;
};
}

View file

@ -3121,8 +3121,6 @@ var ItemTree = class ItemTree extends LibraryTree {
this.tree.invalidateRow(this._rowMap[id]);
}
}
// Update aria-activedescendant on the tree
this.forceUpdate();
this.duplicateMouseSelection = false;
if (shouldDebounce) {
this._onSelectionChangeDebounced();