Skip to content

DataViews: Improve keyboard accessibility in table layout #56328

@andrewhayward

Description

@andrewhayward

Related: #55083

What problem does this address?

Currently every focusable element (or "widget") in a list layout (header action buttons, linked items, etc) presents as its own tab stop. This can make it difficult and tedious for a non-mouse user to move across content.

The Data Views list layout, showing the tab flow across the table.

What is your proposed solution?

If the number of widgets is large, replacing the table with a grid can dramatically reduce the length of the page tab sequence because a grid is a composite widget that can contain other widgets. 1

Rather than rely purely on <table> semantics to render data in a list layout, we should extend this by using a grid widget:

A grid widget is a container that enables users to navigate the information or interactive elements it contains using directional navigation keys, such as arrow keys, Home, and End.
...
A grid can be used to present tabular information that has column titles, row titles, or both. The grid pattern is particularly useful if the tabular information is editable or interactive. For example, when data elements are links to more information, rather than presenting them in a static table and including the links in the tab sequence, implementing the grid pattern provides users with intuitive and efficient keyboard navigation of the grid contents as well as a shorter tab sequence for the page. 2

The Data Views list layout, showing the tab flow if a grid widget was implemented.

Note that navigable widgets within a grid view do not have to map to logical table columns:

The Data Views list layout, showing table columns circled in blue, and individual widgets circled in red.

Because of this, we will probably have to introduce an API of some sort that allows field renderers to capture this widget information, so that this information can be detached:

const fields = [
  ...
  {
    id: "title",
    render: ( { item, Widget } ) => (
      <Widget render={ <Link ... /> }>{ title }</Widget>
    ),
    ...
  },
  {
    id: "actions",
    render: ( { item, Widget } ) => (
      <Widget render={ <Button ... /> }><IconView /></Widget>
      <Widget render={ <Button ... /> }><IconDelete /></Widget>
    ),
    ...
  },
  ...
];

Depending on the layout, this widget component could either be ignored, or utilised to establish better keyboard navigation.

Footnotes

  1. W3 Table Pattern

  2. W3 Grid Pattern

Metadata

Metadata

Assignees

Labels

[Feature] DataViewsWork surrounding upgrading and evolving views in the site editor and beyond[Focus] Accessibility (a11y)Changes that impact accessibility and need corresponding review (e.g. markup changes).[Status] In ProgressTracking issues with work in progress[Type] EnhancementA suggestion for improvement.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions