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

[EuiCodeBlock] Improve accessibility of expandable code blocks #8195

Merged
merged 6 commits into from
Dec 4, 2024

Conversation

mgadewoll
Copy link
Contributor

@mgadewoll mgadewoll commented Nov 28, 2024

Summary

closes #8175.

This PR aims to improve the accessibility of the EuiCodeBlock component, especially the expandable/fullscreen functionality.

Accessibility issues

  1. focusable code blocks did not have any semantic information (the code block is focusable when a height is set to provide scrolling via arrow keys - similar to a listbox pattern)
  2. entering fullscreen mode (expanded code block) did not announce the change to screen reader users
  3. closing the fullscreen mode via the collapse button did not return the focus to the toggle button

Changes

  1. focusable code blocks did not have any semantic information

<pre> elements don't have any semantic information (without adding a specific role) and hence also don't support aria-label to add additional semantic information directly. <code> elements don't accept aria-label and similar attributes either.

To address this a screen-reader only text was added inside the element to be read with the content. This includes the language prop of the code block to increase context.

// example for language="html"

html code block:
<p>
  <!-- Hello world -->
</p>
  1. entering fullscreen mode (expanded code block) did not announce the change to screen reader users

The fullscreen wrapper was not semantically marked and therefore did not provide any information about context change. The container is fullscreen and it has a focus trap, therefore it should be semantically defined as a dialog. Additionally this allows to apply an aria-label to the element, providing context on opening the dialog.

This will result in the following experience:

  • user opens dialog (expands code block)

screen reader output: "Expanded code bock, dialog"
depending on setting the screen reader might read the content of the dialog

  • the code block is focused

screen reader reads: html code block: <p> ...

  • ArrowUp/Down keys navigate the code block content line by line (screen reader browse modes)
  • Escape key anywhere in the dialog closes the dialog and returns the focus to the expand button
  • clicking the collapse button or pressing Enter key on it closes the dialog and returns the focus to the expand button
  1. closing the fullscreen mode via the collapse button did not return the focus to the toggle button

This PR adds a small change to the toggle functionality to ensure the focus is returned to the expand button when closing the fullscreen dialog.

Testing

NVDA

Screen.Recording.2024-11-28.at.15.37.22.mov

Screenshot 2024-11-28 at 15 37 58

JAWS

Screen.Recording.2024-11-28.at.15.35.41.mov

Screenshot 2024-11-28 at 15 36 31

QA

  • open the EuiCodeBlock story and set the overflowHeight control to 50 to reduce the height and enable the expandable code block

#generic

  • verify the code block can be navigated entirely by keyboard
  • verify there is no regression (Storybook, EUI docs) in functionality with production (Storybook, EUI docs)
  • verify that copying the code of a code block does not include the screen reader only label

#a11y

  • verify the component provides sufficient semantic context and focus management
    • verify the code block screen-reader only label is read, announcing it as code block of a specific type (depending on language prop)
    • verify the fullscreen element is a dialog and aria-label is read on opening (reading "Expanded code block, dialog")
    • verify dialog content can be navigated and closed with screen reader navigation and default keyboard navigation

General checklist

@mgadewoll mgadewoll marked this pull request as ready for review November 28, 2024 18:55
@mgadewoll mgadewoll requested a review from a team as a code owner November 28, 2024 18:55
Copy link
Contributor

@weronikaolejniczak weronikaolejniczak left a comment

Choose a reason for hiding this comment

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

The changes look clean and the result is as expected, yay! 🥳 The code block is announced correctly both on focus and expansion.

I tried EuiCodeBlock with and without overflowHeight and isCopyable set.

2 questions:

  • Do you think it would be sensible to cover this by an automated a11y test?
  • Do we want this first approved by an accessibility contractor? Maybe it would be useful to make it a part of all (/most) accessibility tickets and have this check in the PR template?

Role and label:

Screenshot 2024-11-29 at 15 24 48

VoiceOver:

no overflowHeight set:

Screen.Recording.2024-11-29.at.15.10.26.mov

overflowHeight set to 1:

Screen.Recording.2024-11-29.at.15.11.01.mov

overflowHeight set to 1 and isCopyable to true:

Screen.Recording.2024-11-29.at.15.13.13.mov

Note: IMO the UX for copying the content could be improved. There's no information that the content has been copied on clicking the button.


I have 2 more suggestions and a question below 👇🏻

@mgadewoll
Copy link
Contributor Author

@L1nBra Could you have a look as well (ref original issue)?

@mgadewoll
Copy link
Contributor Author

mgadewoll commented Nov 29, 2024

@weronikaolejniczak

Do you think it would be sensible to cover this by an automated a11y test?

We could add a general test to cover keyboard navigation, yes. Beyond that we couldn't test much further as we can't assert screen reader output. (unless we implement something like guidepup)

Do we want this first approved by an accessibility contractor? Maybe it would be useful to make it a part of all (/most) accessibility tickets and have this check in the PR template?

Thanks for the reminder, I wanted to ping the contractor yesterday but forgot 😅

I'm not sure this needs to be a standard per se. 🤔 If we add it we should make it a) optional (default) and b) non-blocker.
I do think it's sensible to add the contractor if they raised the issue or if we have additional questions. But I think they might already have a lot on their plates and might not always be very responsive which could create bottlenecks. The baseline we can handle within the team I think.
But I'm open for opinions 🙂

@mgadewoll
Copy link
Contributor Author

@weronikaolejniczak Thanks for checking in VoiceOver! That's great to have an additional check. Just fyi, we need to keep in mind that VoiceOver is not the screen reader used by the majority of screen reader users. (there is no statistics but the regular Webaim screen reader surveys give us some idea)
Therefore we should always ensure to verify NVDA and/or JAWS on Windows mainly, while VoiceOver can be an additional check (that also means we optimize for Windows screen readers if the experience diverges) 🙂

@weronikaolejniczak
Copy link
Contributor

weronikaolejniczak commented Dec 2, 2024

We could add a general test to cover keyboard navigation, yes. Beyond that we couldn't test much further as we can't assert screen reader output. (unless we implement something like guidepup)

Whatever you feel is worth it here. I would cover keyboard navigation, assert focus and labels, and if you want to go outside of the scope and assert screen reader output, amazing! 👍🏻

But I think they might already have a lot on their plates and might not always be very responsive which could create bottlenecks.

That's very true! I agree, we shouldn't make it a requirement, I would add it as a check "If applicable (...)" after the current accessibility check, just for there to be a reminder when we open a PR 😄 I can mention this in our Slack channel and we can discuss there.

Just fyi, we need to keep in mind that VoiceOver is not the screen reader used by the majority of screen reader users.

That's a very good point, thanks for bringing this up! 💚 Since you tested with NVDA and JAWS, and even provided videos, I figured - why not do this additional check with VoiceOver 🤷🏻‍♀️ In most surveys it comes as third so it's definitely worth checking.

I'm going to leave an approve here, feel free to ping me if something changes after the a11y review and potential test fixes 😄

@mgadewoll
Copy link
Contributor Author

mgadewoll commented Dec 3, 2024

Note: IMO the UX for copying the content could be improved. There's no information that the content has been copied on clicking the button.

@weronikaolejniczak NVDA and JAWS work fine here. The EuiCopy component sets a "copied" message as tooltip (code) which is announced. VoiceOver is the outlier here by not announcing it.
There might be general improvements we could check around it - e.g. the "copied" status should probably be reset when the focus is moved away from the copy button or we should translate the "Copied" message properly. But for this task, imho, there is nothing to add for now.

JAWS
Screenshot 2024-12-03 at 11 11 50

NVDA
Screenshot 2024-12-03 at 11 12 48

@mgadewoll mgadewoll force-pushed the codeblock/8175-a11y-improvements branch from 3b23b17 to 785ac3e Compare December 3, 2024 10:22
@kibanamachine
Copy link

Preview staging links for this PR:

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

@L1nBra
Copy link

L1nBra commented Dec 4, 2024

Checked with keyboard, NVDA screen reader on Windows 11 Chrome browser from A11y side:
-when user expands code block - announcement is made.
-dialog is announced for the user and what is present in code block is also announced.
-after collapsing code block, focus is on Expand button and it is announced.
-code block, expand/collapse buttons are accessible with keyboard.
From a11y side it works correctly.

@mgadewoll mgadewoll merged commit d6119ee into elastic:main Dec 4, 2024
5 checks passed
mgadewoll added a commit to elastic/kibana that referenced this pull request Dec 19, 2024
`v98.1.0-borealis.0`⏩`v98.2.1-borealis.2`

_[Questions? Please see our Kibana upgrade
FAQ.](https://github.com/elastic/eui/blob/main/wiki/eui-team-processes/upgrading-kibana.md#faq-for-kibana-teams)_

---

# `@elastic/eui`

## [`v98.2.1`](https://github.com/elastic/eui/releases/v98.2.1)

- Updated the EUI theme color values to use a full 6 char hex code
format ([#8244](elastic/eui#8244))

## [`v98.2.0`](https://github.com/elastic/eui/releases/v98.2.0)

- Added two new icons: `contrast` and `contrastHigh`
([#8216](elastic/eui#8216))
- Updated `EuiDataGrid` content to have a transparent background.
([#8220](elastic/eui#8220))

**Accessibility**

- When the tooltips components (`EuiTooltip`, `EuiIconTip`) are used
inside components that handle the Escape key (like `EuiFlyout` or
`EuiModal`), pressing the Escape key will now only close the tooltip and
not the entire wrapping component.
([#8140](elastic/eui#8140))
- Improved the accessibility of `EuiCodeBlock`s by
([#8195](elastic/eui#8195))
  - adding screen reader only labels
  - adding `role="dialog"` on in fullscreen mode
  - ensuring focus is returned on closing fullscreen mode
  
# Borealis updates
  
- [Visual Refresh] Update color token mappings
([#8211](elastic/eui#8211))
- [Visual Refresh] Introduce shared popover arrow styles to Borealis
([#8212](elastic/eui#8212))
- [Visual Refresh] Add forms.maxWidth token
([#8221](elastic/eui#8221))
- [Visual Refresh] Set darker shade for subdued text
([#8224](elastic/eui#8224))
- [Visual Refresh] Remove support for accentSecondary badges
([#8224](elastic/eui#8227))
- [Visual Refresh] Add severity vis colors
([#8247](elastic/eui#8247))
- [Visual Refresh] Fix transparent color variable definitions
([8249](elastic/eui#8249))
- [Visual Refresh] Update EuiToken colors
([8250](elastic/eui#8250))

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
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.

[EuiCodeBlock] Check and improve accessibility of expanding code blocks
5 participants