Unplanned
Last Updated: 01 Mar 2022 06:22 by ADMIN
Jeff
Created on: 28 Feb 2022 14:23
Category: KendoReact
Type: Feature Request
0
Grid Accessibility Improvements; Aria attributes, caption.

A few suggestions for the React Grid (as of v5.0.1) to help devs conform to accessibility compliance...

1) Standard HTML tables can contains a <caption> element, which screenreaders will use as the descriptive name of the table. Kendo Grid does not appear to have any way to name the table.

2) Related to number 1, other ways to assign a descriptive name to a table may be to include a `title`, `aria-label` or `aria-describedby` attributes, but none of these work on <Grid>. They are not rendered into the HTML if passed as props.

3) Allow GridCell and other Cell components to take `children` to render. The current documentation generally advises us to override the `cell={}` prop on a GridColumn for custom cell rendering. What is not listed in the docs is that doing what seems like the obvious thing:

<GridColumn cell={() => <td>myContent</td>} />

actually breaks accessibility. At a minimum the cell MUST get the attributes

            role={'gridcell'}
            aria-colindex={props.ariaColumnIndex}

to have the table actually be represented correctly in most screen readers. The Kendo <GridCell> component would normally add these, but only renders the field from the dataItem. It can only render custom data if the `render` prop is set, in which case it yet again does not render the `<td role= aria-colindex=` portions on it's own.

What I'm getting at is, everyone who ever wanted to render a custom cell in Keno Grid always had to make their own cell component that added at least the `role` and `aria-colindex` attributes, and if they didn't, they probably unknowingly broke accessibility.

Kendo could make this clearer in the docs (including the accessibility page for the Grid), and could easily alter GridCell to render `children` if they are passed. Then we could do:

<GridColumn cell={<GridCell><button>yay</button></GridCell>} />

and have the rendered HTML:

<td colSpan="1" style="" class="" role="gridcell" aria-colindex="1" aria-selected="false"><button>yay</button></td>

I think in GridCell this would be as easy as changing:

        defaultRendering = (
          <td
            colSpan={props.colSpan}
            style={props.style}
            className={className}
            role={'gridcell'}
            aria-colindex={props.ariaColumnIndex}
            aria-selected={props.isSelected}
            {...{[GRID_COL_INDEX_ATTRIBUTE]: props.columnIndex}}
            {...navigationAttributes}
          >
            {dataAsString}
          </td>
to:
        defaultRendering = (
          <td
            colSpan={props.colSpan}
            style={props.style}
            className={className}
            role={'gridcell'}
            aria-colindex={props.ariaColumnIndex}
            aria-selected={props.isSelected}
            {...{[GRID_COL_INDEX_ATTRIBUTE]: props.columnIndex}}
            {...navigationAttributes}
          >
            {children || dataAsString}
          </td>

2 comments
ADMIN
Stefan
Posted on: 01 Mar 2022 06:22

Hello,

Thank you for all of the detailed suggestions.

Our accessibility specialists will review all of them and plan them accordingly.

We will update the item once we have made progress on it.

Regards,
Stefan
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Jeff
Posted on: 28 Feb 2022 15:28

4) One of the basic parts of HTML table accessibility is the <th> element's `scope` property

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th#attr-scope

https://www.w3.org/WAI/tutorials/tables/two-headers/

but there seems to be no way to pass a `scope` to a <GridColumn> or a Header cell. The <HeaderThElement> component doesn't have `scope` as a prop. This comes back to the same problem as number 3 above; making an accessible Grid that has row headers means having to rewrite all the rendering of the default Grid as custom components, because standard HTML attributes are not passed-through to the rendered HTML.