Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiDataGrid] Improve aria row counts and indices for screen reader users #6033

Merged
merged 5 commits into from
Jul 8, 2022

Conversation

cee-chen
Copy link
Member

@cee-chen cee-chen commented Jul 6, 2022

Summary

Please see inline code comments below that highlight changes & include screen reader before/after screencaps.

Checklist

  • Checked in Chrome, Safari, Edge, and Firefox
  • Added or updated jest and cypress tests
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

- this enables row counts in virtualized grids to be correctly announced (instead of only counting the rendered rows)

- NOTE: This works in VO+Safari but not VO+FF
- which requires passing `pagination` down to `EuiDataGridCell` and adding # of paginated rows to the visible row index
- add column header name/ID in parenthesis after column index

- fix row index - was not correct on sort, and should now do so

- add `-` for extra spacing between cell content and cell data, remove `:` for more natural speech cadence
@cee-chen cee-chen requested a review from 1Copenut July 6, 2022 20:20
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_6033/

@@ -420,6 +420,7 @@ export const EuiDataGrid = forwardRef<EuiDataGridRefProps, EuiDataGridProps>(
data-test-subj="euiDataGridBody"
className="euiDataGrid__content"
role="grid"
aria-rowcount={rowCount}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without aria-rowcount, screen readers are reporting the wrong total rows for virtualized grids (because they're only counting the actual number of DOM nodes present, which is inaccurate due to virtualization).

Before

After

Copy link
Member Author

@cee-chen cee-chen Jul 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also note that VO+Firefox does not appear to respect/announce aria-rowcount, while Safari and Chrome appear to.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Firefox + VO not honoring aria-rowcount seems like a 🐞 worth filing with Mozilla. I'll do that this afternoon.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be awesome to mention that aria-sort on FF/VO also does nothing!

@@ -686,6 +699,7 @@ export class EuiDataGridCell extends Component<
const content = (
<div
role="gridcell"
aria-rowindex={ariaRowIndex}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without aria-rowindex and aria-rowcount, the automatic table/gridcell announcement that occurs when using screen reader navigation* (ctrl+opt+arrow keys VS. just arrow keys) is off.

Before

After

*Caveat

While this is a relatively minor and low-cost addition, @1Copenut and I discussed screen reader browsing/navigation behavior on data grids and came to the conclusion they will never be optimized vs. using regular arrow keys, for a few key reasons:

  1. Screen reader navigation does not trigger focus (unless navigating to a focusable child within a grid cell) on a grid cell and as such the 'current cell' falls out of date. This is reproducible on W3's own datagrid example: https://www.w3.org/WAI/ARIA/apg/example-index/grid/dataGrids
  2. Since screen reader navigation doesn't scroll grids, it will never work properly with scrolling virtualized grids

Comment on lines 95 to 106
<p>
{'- '}
<EuiI18n
token="euiDataGridCell.position"
default="Row {row}, Column {col} ({columnId})"
values={{
row: ariaRowIndex,
col: colIndex + 1,
columnId: column?.displayAsText || rest.columnId,
}}
/>
</p>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the (column Name/ID) in parenthesis helps contextualize the cell more, similar to default aria table behavior. I changed the - and : punctuation for a more natural sounding voice flow - let me know what you think!

Before:

(Note: GH's video player appears to start muted, be sure to unmute it)

before.mp4

After

(Note: GH's video player appears to start muted, be sure to unmute it)

after.mp4

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been listening to this read back all morning and thinking of it in terms of data importance priority. (I totally made that up). I swapped the Column Name/ID ahead of the row and column number combo. Putting myself in the place of a user digging through a column of data, I wanted to hear the data first, then the label, then my position in the grid. What do you think about swapping line 99 to be

! data_grid_cell#L99

<EuiScreenReaderOnly>
  <p>
    {'- '}
      <EuiI18n
        token="euiDataGridCell.position"
-       default="Row {row}, Column {col} ({columnId})"
+       default="{columnId}. Row {row}, Column {col}."
        values={{
        row: ariaRowIndex,
        col: colIndex + 1,
        columnId: column?.displayAsText || rest.columnId,
      }}
    />
  </p>
</EuiScreenReaderOnly>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't disagree on column label/title feeling like it should come before position, but I also simultaneously feel like it makes sense to keep the column name and column index together since they're related 🤔 how about something like

{Column Title}, column {number}, row {number}
e.g., Amount, Column 2, Row 8

Not sure if this matters also, but it might be worth nothing that some column titles are extremely technical and long in Kibana and not nice and human-readable, e.g. destination.ip_address or similar

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@constancecchen Good call. Let's keep the column name and index together.

Your point about some Kibana column titles being technical and long is spot on. It matters, but how much is a sliding scale. I'm floating the idea elsewhere, and feel the benefits outweigh the increased cognitive load. If research proves out otherwise, we can always revisit this solution.

Copy link
Member Author

@cee-chen cee-chen Jul 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha! So just to confirm, do you want to stay with the current copy, or do you want to change it to:

Suggested change
<p>
{'- '}
<EuiI18n
token="euiDataGridCell.position"
default="Row {row}, Column {col} ({columnId})"
values={{
row: ariaRowIndex,
col: colIndex + 1,
columnId: column?.displayAsText || rest.columnId,
}}
/>
</p>
<p>
{'- '}
<EuiI18n
token="euiDataGridCell.position"
default="{columnId}, column {col}, row {row}"
values={{
row: ariaRowIndex,
col: colIndex + 1,
columnId: column?.displayAsText || rest.columnId,
}}
/>
</p>

?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change it to the default="{columnId}, column {col}, row {row}" you proposed in the green addition.

My apologies, comment clarity is a work in progress.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cee-chen
Copy link
Member Author

cee-chen commented Jul 6, 2022

One more thing worth noting - it appears we do not need aria-colcount or aria-colindex as we do not virtualize our sticky header cells with role="columnheader", and as such / because they're always present, the column count is always correct. Feel free to test/confirm this however Trevor, once staging is up

@cee-chen cee-chen marked this pull request as ready for review July 6, 2022 21:24
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_6033/

Copy link
Contributor

@1Copenut 1Copenut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aria additions are significant improvements for virtualized and paginated tables. It gives a proper context and informs users of the potential cognitive load involved in parsing data. Much appreciated!

I have just one change request, noted in its own comment.

The changes drove really well in Safari + VO, and I'll give them a second pass in Safari and Firefox later today.

Comment on lines 95 to 106
<p>
{'- '}
<EuiI18n
token="euiDataGridCell.position"
default="Row {row}, Column {col} ({columnId})"
values={{
row: ariaRowIndex,
col: colIndex + 1,
columnId: column?.displayAsText || rest.columnId,
}}
/>
</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been listening to this read back all morning and thinking of it in terms of data importance priority. (I totally made that up). I swapped the Column Name/ID ahead of the row and column number combo. Putting myself in the place of a user digging through a column of data, I wanted to hear the data first, then the label, then my position in the grid. What do you think about swapping line 99 to be

! data_grid_cell#L99

<EuiScreenReaderOnly>
  <p>
    {'- '}
      <EuiI18n
        token="euiDataGridCell.position"
-       default="Row {row}, Column {col} ({columnId})"
+       default="{columnId}. Row {row}, Column {col}."
        values={{
        row: ariaRowIndex,
        col: colIndex + 1,
        columnId: column?.displayAsText || rest.columnId,
      }}
    />
  </p>
</EuiScreenReaderOnly>

@@ -420,6 +420,7 @@ export const EuiDataGrid = forwardRef<EuiDataGridRefProps, EuiDataGridProps>(
data-test-subj="euiDataGridBody"
className="euiDataGrid__content"
role="grid"
aria-rowcount={rowCount}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Firefox + VO not honoring aria-rowcount seems like a 🐞 worth filing with Mozilla. I'll do that this afternoon.

@1Copenut
Copy link
Contributor

1Copenut commented Jul 7, 2022

One more thing worth noting - it appears we do not need aria-colcount or aria-colindex as we do not virtualize our sticky header cells with role="columnheader", and as such / because they're always present, the column count is always correct. Feel free to test/confirm this however Trevor, once staging is up

👍 I concur. Getting accurate counts of columns in Safari and Firefox + VO.

@cee-chen cee-chen requested a review from 1Copenut July 8, 2022 16:16
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_6033/

Copy link
Contributor

@1Copenut 1Copenut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new order of announcement sounds great, and feels correct for aural UX. Code changes tested in Safari and Firefox with VoiceOver. Thanks @constancecchen !

@cee-chen cee-chen merged commit d0bcd50 into elastic:main Jul 8, 2022
@cee-chen cee-chen deleted the datagrid/aria-attrs branch July 8, 2022 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants