Skip to content

Commit 48690d6

Browse files
fix: adjust aria-rowcount and aria-colcount based on grid state (#9872) (#9892)
Co-authored-by: Diego Cardoso <diego@vaadin.com>
1 parent 98674ba commit 48690d6

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

packages/grid/src/vaadin-grid-a11y-mixin.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const A11yMixin = (superClass) =>
2222
};
2323
}
2424
static get observers() {
25-
return ['_a11yUpdateGridSize(size, _columnTree)'];
25+
return ['_a11yUpdateGridSize(size, _columnTree, __emptyState)'];
2626
}
2727

2828
/** @private */
@@ -34,21 +34,27 @@ export const A11yMixin = (superClass) =>
3434

3535
/** @private */
3636
_a11yGetFooterRowCount(_columnTree) {
37-
return _columnTree.filter((level) => level.some((col) => col.headerRenderer)).length;
37+
return _columnTree.filter((level) => level.some((col) => col.footerRenderer)).length;
3838
}
3939

4040
/** @private */
41-
_a11yUpdateGridSize(size, _columnTree) {
41+
_a11yUpdateGridSize(size, _columnTree, emptyState) {
4242
if (size === undefined || _columnTree === undefined) {
4343
return;
4444
}
4545

46+
const headerRowsCount = this._a11yGetHeaderRowCount(_columnTree);
47+
const footerRowsCount = this._a11yGetFooterRowCount(_columnTree);
48+
const bodyRowsCount = emptyState ? 1 : size;
49+
const rowsCount = bodyRowsCount + headerRowsCount + footerRowsCount;
50+
51+
this.$.table.setAttribute('aria-rowcount', rowsCount);
52+
4653
const bodyColumns = _columnTree[_columnTree.length - 1];
47-
this.$.table.setAttribute(
48-
'aria-rowcount',
49-
size + this._a11yGetHeaderRowCount(_columnTree) + this._a11yGetFooterRowCount(_columnTree),
50-
);
51-
this.$.table.setAttribute('aria-colcount', (bodyColumns && bodyColumns.length) || 0);
54+
// If no header and footer rows while the empty state is active, count as one column
55+
// Otherwise, use the number of body columns, if present
56+
const columnsCount = emptyState ? 1 : (rowsCount && bodyColumns && bodyColumns.length) || 0;
57+
this.$.table.setAttribute('aria-colcount', columnsCount);
5258

5359
this._a11yUpdateHeaderRows();
5460
this._a11yUpdateFooterRows();

packages/grid/src/vaadin-grid-mixin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ export const GridMixin = (superClass) =>
640640

641641
// Make sure the section has a tabbable element
642642
this._resetKeyboardNavigation();
643+
this._a11yUpdateGridSize(this.size, this._columnTree, this.__emptyState);
643644
}
644645

645646
/** @private */

packages/grid/test/accessibility.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,19 @@ describe('accessibility', () => {
239239
await nextFrame();
240240
expect(grid.$.table.getAttribute('aria-colcount')).to.equal('4');
241241
});
242+
243+
it('should update aria-colcount when grid is empty with empty-state and no header/footer rendered', async () => {
244+
const emptyStateText = document.createElement('span');
245+
emptyStateText.setAttribute('slot', 'empty-state');
246+
grid.appendChild(emptyStateText);
247+
grid.querySelectorAll('vaadin-grid-column').forEach((col) => {
248+
col.headerRenderer = null;
249+
col.footerRenderer = null;
250+
});
251+
grid.items = [];
252+
await nextFrame();
253+
expect(grid.$.table.getAttribute('aria-colcount')).to.equal('1');
254+
});
242255
});
243256

244257
describe('row details in use', () => {
@@ -313,6 +326,26 @@ describe('accessibility', () => {
313326
// 10 item rows + header row + footer row = 12 in total
314327
expect(grid.$.table.getAttribute('aria-rowcount')).to.equal('12');
315328
});
329+
330+
it('should count the footer rows correctly as part of the aria-rowcount', async () => {
331+
// Remove the header renderers
332+
grid.querySelectorAll('vaadin-grid-column').forEach((col) => {
333+
col.headerRenderer = null;
334+
});
335+
336+
await nextFrame();
337+
expect(grid.$.table.getAttribute('aria-rowcount')).to.equal('3');
338+
});
339+
340+
it('should count the header rows correctly as part of the aria-rowcount', async () => {
341+
// Remove the footer renderers
342+
grid.querySelectorAll('vaadin-grid-column').forEach((col) => {
343+
col.footerRenderer = null;
344+
});
345+
346+
await nextFrame();
347+
expect(grid.$.table.getAttribute('aria-rowcount')).to.equal('3');
348+
});
316349
});
317350

318351
describe('group', () => {

0 commit comments

Comments
 (0)