Skip to content

Commit

Permalink
Fixed #921 - Accessibility of the DataTable expander cell button
Browse files Browse the repository at this point in the history
  • Loading branch information
mertsincan committed Mar 5, 2021
1 parent 77416f7 commit 79e7626
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 24 deletions.
5 changes: 3 additions & 2 deletions src/components/datatable/BodyCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,15 @@ export class BodyCell extends Component {

if (this.props.expander) {
const iconClassName = classNames('p-row-toggler-icon pi pi-fw p-clickable', { 'pi-chevron-down': this.props.expanded, 'pi-chevron-right': !this.props.expanded });
const ariaControls = `${this.props.tableId ? this.props.tableId + '_' : ''}content_${this.props.rowIndex}_expanded`;
let expanderProps = {
onClick: this.onExpanderClick,
className: 'p-row-toggler p-link',
iconClassName
};

content = (
<button type="button" onClick={expanderProps.onClick} className={expanderProps.className}>
<button type="button" onClick={expanderProps.onClick} className={expanderProps.className} aria-expanded={this.props.expanded} aria-controls={ariaControls}>
<span className={expanderProps.iconClassName}></span>
<Ripple />
</button>
Expand Down Expand Up @@ -319,7 +320,7 @@ export class BodyCell extends Component {
}

return (
<td ref={(el) => { this.container = el; }} className={cellClassName} style={this.props.bodyStyle || this.props.style} onClick={this.onClick} onKeyDown={this.onKeyDown}
<td ref={(el) => { this.container = el; }} role="cell" className={cellClassName} style={this.props.bodyStyle || this.props.style} onClick={this.onClick} onKeyDown={this.onKeyDown}
rowSpan={this.props.rowSpan} onBlur={this.onBlur}>
{header}
{editorKeyHelper}
Expand Down
4 changes: 2 additions & 2 deletions src/components/datatable/BodyRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export class BodyRow extends Component {
}
}

let cell = <BodyCell key={i} {...column.props} value={this.props.value} rowSpan={rowSpan} rowData={this.props.rowData} rowIndex={this.props.rowIndex} onRowToggle={this.props.onRowToggle} expanded={this.props.expanded}
let cell = <BodyCell tableId={this.props.tableId} key={i} {...column.props} value={this.props.value} rowSpan={rowSpan} rowData={this.props.rowData} rowIndex={this.props.rowIndex} onRowToggle={this.props.onRowToggle} expanded={this.props.expanded}
onRadioClick={this.props.onRadioClick} onCheckboxClick={this.props.onCheckboxClick} selected={this.props.selected}
editMode={this.props.editMode} editing={this.state.editing} onRowEditInit={this.onRowEditInit} onRowEditSave={this.onRowEditSave} onRowEditCancel={this.onRowEditCancel}
showRowReorderElement={this.props.showRowReorderElement} showSelectionElement={this.props.showSelectionElement}/>;
Expand All @@ -263,7 +263,7 @@ export class BodyRow extends Component {
}

return (
<tr tabIndex={this.props.selectionMode ? 0 : null} ref={(el) => {this.container = el;}} className={className} onClick={this.onClick} onDoubleClick={this.onDoubleClick} onTouchEnd={this.onTouchEnd} onContextMenu={this.onRightClick} onMouseDown={this.onMouseDown}
<tr role="row" tabIndex={this.props.selectionMode ? 0 : null} ref={(el) => {this.container = el;}} className={className} onClick={this.onClick} onDoubleClick={this.onDoubleClick} onTouchEnd={this.onTouchEnd} onContextMenu={this.onRightClick} onMouseDown={this.onMouseDown}
onDragStart={this.props.onDragStart} onDragEnd={this.onDragEnd} onDragOver={this.onDragOver} onDragLeave={this.onDragLeave} onDrop={this.onDrop} style={style} onKeyDown={this.onKeyDown}>
{cells}
</tr>
Expand Down
2 changes: 1 addition & 1 deletion src/components/datatable/DataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,7 @@ export class DataTable extends Component {
}

createTableBody(value, columns, frozen) {
return <TableBody value={value} first={this.getFirst()} rows={this.getRows()} lazy={this.props.lazy} paginator={this.props.paginator} dataKey={this.props.dataKey} compareSelectionBy={this.props.compareSelectionBy}
return <TableBody tableId={this.props.id} value={value} first={this.getFirst()} rows={this.getRows()} lazy={this.props.lazy} paginator={this.props.paginator} dataKey={this.props.dataKey} compareSelectionBy={this.props.compareSelectionBy}
selectionMode={this.props.selectionMode} selection={this.props.selection} metaKeySelection={this.props.metaKeySelection} frozen={frozen} frozenSelectionMode={this.frozenSelectionMode}
onSelectionChange={this.props.onSelectionChange} onRowClick={this.props.onRowClick} onRowDoubleClick={this.props.onRowDoubleClick} onRowSelect={this.props.onRowSelect} onRowUnselect={this.props.onRowUnselect}
contextMenuSelection={this.props.contextMenuSelection} onContextMenuSelectionChange={this.props.onContextMenuSelectionChange} onContextMenu={this.props.onContextMenu}
Expand Down
2 changes: 1 addition & 1 deletion src/components/datatable/FooterCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class FooterCell extends Component {
let footer = ObjectUtils.getJSXElement(this.props.footer, this.props);

return (
<td className={className} style={this.props.footerStyle||this.props.style}
<td role="cell" className={className} style={this.props.footerStyle||this.props.style}
colSpan={this.props.colSpan} rowSpan={this.props.rowSpan}>
{footer}
</td>
Expand Down
4 changes: 2 additions & 2 deletions src/components/datatable/HeaderCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export class HeaderCell extends Component {

if (this.props.renderOptions.filterOnly) {
return (
<th ref={(el) => this.el = el} className={classNames('p-filter-column', this.props.columnProps.filterHeaderClassName)} style={this.props.columnProps.filterHeaderStyle||this.props.columnProps.style}
<th ref={(el) => this.el = el} role="columnheader" className={classNames('p-filter-column', this.props.columnProps.filterHeaderClassName)} style={this.props.columnProps.filterHeaderStyle||this.props.columnProps.style}
colSpan={this.props.columnProps.colSpan} rowSpan={this.props.columnProps.rowSpan}>
{filterElement}
{headerCheckbox}
Expand Down Expand Up @@ -192,7 +192,7 @@ export class HeaderCell extends Component {
let sortBadge = this.renderSortBadge(sortMetaDataIndex);

return (
<th ref={(el) => this.el = el} tabIndex={this.props.columnProps.sortable ? this.props.tabIndex : null}
<th ref={(el) => this.el = el} role="columnheader" tabIndex={this.props.columnProps.sortable ? this.props.tabIndex : null}
className={className} style={this.props.columnProps.headerStyle||this.props.columnProps.style} onClick={this.onClick} onMouseDown={this.onMouseDown} onKeyDown={this.onKeyDown}
colSpan={this.props.columnProps.colSpan} rowSpan={this.props.columnProps.rowSpan} aria-sort={ariaSortData}
onDragStart={this.props.onDragStart} onDragOver={this.props.onDragOver} onDragLeave={this.props.onDragLeave} onDrop={this.props.onDrop}>
Expand Down
19 changes: 10 additions & 9 deletions src/components/datatable/TableBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ export class TableBody extends Component {
}

return (
<tr key={index + '_rowgroupheader'} className="p-rowgroup-header">
<td colSpan={React.Children.count(this.props.children)}>
<tr role="row" key={index + '_rowgroupheader'} className="p-rowgroup-header">
<td role="cell" colSpan={React.Children.count(this.props.children)}>
{ content }
<span className="p-rowgroup-header-name">
{this.props.rowGroupHeaderTemplate(rowData, index)}
Expand All @@ -473,7 +473,7 @@ export class TableBody extends Component {

renderRowGroupFooter(rowData, index) {
return (
<tr key={index + '_rowgroupfooter'} className="p-rowgroup-footer">
<tr role="row" key={index + '_rowgroupfooter'} className="p-rowgroup-footer">
{this.props.rowGroupFooterTemplate(rowData, index)}
</tr>
);
Expand Down Expand Up @@ -543,7 +543,7 @@ export class TableBody extends Component {
let isRowGroupExpanded = this.props.expandableRowGroups && hasSubheaderGrouping && rowGroupHeaderExpanded;
if (!this.props.expandableRowGroups || isRowGroupExpanded) {
//row content
let bodyRow = <BodyRow key={i} value={this.props.value} rowData={rowData} rowIndex={i} onClick={this.onRowClick} onDoubleClick={this.props.onRowDoubleClick} onRightClick={this.onRowRightClick} onTouchEnd={this.onRowTouchEnd}
let bodyRow = <BodyRow tableId={this.props.tableId} key={i} value={this.props.value} rowData={rowData} rowIndex={i} onClick={this.onRowClick} onDoubleClick={this.props.onRowDoubleClick} onRightClick={this.onRowRightClick} onTouchEnd={this.onRowTouchEnd}
onRowToggle={this.onRowToggle} expanded={expanded} selectionMode={this.props.selectionMode}
onRadioClick={this.onRadioClick} onCheckboxClick={this.onCheckboxClick} selected={selected} contextMenuSelected={contextMenuSelected} rowClassName={this.props.rowClassName}
sortField={this.props.sortField} rowGroupMode={this.props.rowGroupMode} groupRowSpan={groupRowSpan}
Expand All @@ -558,14 +558,15 @@ export class TableBody extends Component {
}

//row expansion
if(expanded && !(hasSubheaderGrouping && this.props.expandableRowGroups)) {
if (expanded && !(hasSubheaderGrouping && this.props.expandableRowGroups)) {
let expandedRowContent = this.props.rowExpansionTemplate(rowData);
let expandedRow = <tr key={i + '_expanded'}><td colSpan={this.props.children.length}>{expandedRowContent}</td></tr>
let id = `${this.props.tableId ? this.props.tableId + '_' : ''}content_${i}_expanded`;
let expandedRow = <tr key={id} id={id} role="row"><td role="cell" colSpan={this.props.children.length}>{expandedRowContent}</td></tr>
rows.push(expandedRow);
}

//footer row group
if(hasSubheaderGrouping && (!this.props.expandableRowGroups || isRowGroupExpanded)) {
if (hasSubheaderGrouping && (!this.props.expandableRowGroups || isRowGroupExpanded)) {
let currentRowFieldData = ObjectUtils.resolveFieldData(rowData, this.props.groupField);
let nextRowFieldData = ObjectUtils.resolveFieldData(this.props.value[i + 1], this.props.groupField);

Expand All @@ -579,8 +580,8 @@ export class TableBody extends Component {
let emptyMessage = this.props.emptyMessage;

rows = !this.props.loading && emptyMessage !== null ?
<tr className="p-datatable-emptymessage">
<td colSpan={this.props.children.length}>
<tr role="row" className="p-datatable-emptymessage">
<td role="cell" colSpan={this.props.children.length}>
{
(typeof emptyMessage === 'function') ? emptyMessage(this.props.frozen) : emptyMessage
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/datatable/TableFooter.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export class TableFooter extends Component {
if(this.props.columnGroup) {
let rows = React.Children.toArray(this.props.columnGroup.props.children);
content = rows.map((row, i) => {
return <tr key={i}>{this.createFooterCells(row)}</tr>;
return <tr key={i} role="row">{this.createFooterCells(row)}</tr>;
});
}
else {
content = <tr>{this.createFooterCells(this)}</tr>;
content = <tr role="row">{this.createFooterCells(this)}</tr>;
}

return (
Expand All @@ -29,4 +29,4 @@ export class TableFooter extends Component {
</tfoot>
);
}
}
}
8 changes: 4 additions & 4 deletions src/components/datatable/TableHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class TableHeader extends Component {
if (this.props.columnGroup) {
let rows = React.Children.toArray(this.props.columnGroup.props.children);
content = rows.map((row, i) => {
return <tr key={i}>{this.createHeaderCells(React.Children.toArray(row.props.children), {filterOnly: false, renderFilter: true, renderHeaderCheckbox: true})}</tr>;
return <tr key={i} role="row">{this.createHeaderCells(React.Children.toArray(row.props.children), {filterOnly: false, renderFilter: true, renderHeaderCheckbox: true})}</tr>;
});
}
else {
Expand All @@ -40,13 +40,13 @@ export class TableHeader extends Component {
if (this.hasColumnFilter(columns)) {
content = (
<>
<tr>{this.createHeaderCells(columns, {filterOnly: false, renderFilter: false, renderHeaderCheckbox: false})}</tr>
<tr>{this.createHeaderCells(columns, {filterOnly: true, renderFilter: true, renderHeaderCheckbox: true})}</tr>
<tr role="row">{this.createHeaderCells(columns, {filterOnly: false, renderFilter: false, renderHeaderCheckbox: false})}</tr>
<tr role="row">{this.createHeaderCells(columns, {filterOnly: true, renderFilter: true, renderHeaderCheckbox: true})}</tr>
</>
);
}
else {
content = <tr>{this.createHeaderCells(columns, {filterOnly: false, renderFilter: false, renderHeaderCheckbox: true})}</tr>;
content = <tr role="row">{this.createHeaderCells(columns, {filterOnly: false, renderFilter: false, renderHeaderCheckbox: true})}</tr>;
}
}

Expand Down

0 comments on commit 79e7626

Please sign in to comment.