Skip to content

Conversation

@mgadewoll
Copy link
Contributor

@mgadewoll mgadewoll commented Jul 3, 2025

Summary

closes #8837

This PR updates EuiProgress to ensure that progress updates are announces to screen reader users. Previously users would only be able to know the current progress of the element by manually navigating to it in the DOM.

Changes

  • adds a aria-live region in EuiProgress that mirrors the values of label and value, reading on progress update e.g. Loading 10%
    • ℹ️ Due to the native behavior of aria-live with aria-atomic the initial value will not be output, only updates will trigger an output. This is expected as we don't want the value to be read on mount but only on update. This means we can support static value display as well as loading states.
  • removes the visible label and valueText output from the accessibility tree with aria-hidden:
    • because we're adding an aria-live region with the same text, we prevent duplicate content for screen reader users this way
  • removes aria-hidden on the <progress> element:
    • ℹ️ aria-hidden was used here previously with the assumption that the <progress> element and valueText duplicate each other. This is true but having the <progress> element available in the DOM has a few benefits:
      • a) the element is perceivable in the DOM on user navigation and provides semantic information on demand next to the automatic updates
      • b) the available <progress> element can trigger update sounds (not reading it's value but providing a sound-icon indication of progress) when available
      • c) providing the label and progress aligns the screen reader experience closer with the visual output

Why are we making this change?

This update improves the accessibility of the EuiProgress component by ensuring that users are receiving updates directly without the need to manually focus the component in the DOM.

WCAG 4.1.3 Status Messages

Screenshots

AT valueText={false} valueText={true} valueText={${value} steps}`
NVDA
Screen.Recording.2025-07-03.at.11.23.03.mov
Screen.Recording.2025-07-03.at.11.23.31.mov
Screen.Recording.2025-07-03.at.11.32.51.mov
JAWS

Impact to users

🟢 This PR does not contain breaking changes nor does it require updates on consumer side.

QA

  • checkout this PR and open the newly added story `EuiProgress > Determinate Loading"
    • verify that the progress updates are correctly announced to the screen reader (NVDA/JAWS, VoiceOver)
    • verify that navigating the DOM with the screen reader will read the label/status and progress bar

General checklist

  • Browser QA
    • Checked in both light and dark modes
    • Checked in both MacOS and Windows high contrast modes
    • Checked in mobile
    • Checked in Chrome, Safari, Edge, and Firefox
    • Checked for accessibility including keyboard-only and screenreader modes
  • Docs site QA
  • Code quality checklist
  • Release checklist
    • A changelog entry exists and is marked appropriately.
    • If applicable, added the breaking change issue label (and filled out the breaking change checklist)
  • Designer checklist
    • If applicable, file an issue to update EUI's Figma library with any corresponding UI changes. (This is an internal repo, if you are external to Elastic, ask a maintainer to submit this request)

@mgadewoll mgadewoll self-assigned this Jul 3, 2025
style={customColorStyles}
max={max}
value={value}
aria-hidden={label && valueText ? true : false}
Copy link
Contributor Author

@mgadewoll mgadewoll Jul 3, 2025

Choose a reason for hiding this comment

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

ℹ️ Removing aria-hidden is intentional but I'm open to opinions here.

The previous idea here was that the progress bar is not needed as it's a graphical representation of the valueText.
Why I chose to always have the <progress> element on the accessibility tree has a couple reasons:

  • a) the element is perceivable in the DOM on user navigation and provides semantic information on demand next to the automatic updates (a user navigating to this element will hear it's semantic role and it's aria-valuetext e.g. "progressbar 10%`)
  • b) the available <progress> element can trigger update sounds (not reading it's value but providing a sound-icon indication of progress) when available
  • c) providing the label and progress aligns the semantic screen reader experience closer with the visual output

@mgadewoll mgadewoll marked this pull request as ready for review July 3, 2025 11:58
@mgadewoll mgadewoll requested a review from a team as a code owner July 3, 2025 11:58
@weronikaolejniczak weronikaolejniczak self-requested a review July 3, 2025 12:00
mgadewoll added 2 commits July 4, 2025 11:45
- ensures the  value is reused for the interval functionality

- ensures the interval is cleanup on unmount

- fixes wrong condition value
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 description is 👨🏻‍🍳👌🏻 It made it super easy to understand the issue and what you're proposing. And thanks for applying my suggestions so quickly! 🐎

Having compared the current solution and the version from this PR, I agree with the decision. <progress> in the accessibility tree brings a11y benefits that cannot be easily replicated with custom code.

Announcing the progress seems to be in accordance with the SC 4.1.3, from Understanding WCAG "Status Message":

An application displays a progressbar to indicate the status of an upgrade. The element is assigned a suitable role. The screen reader provides intermittent announcements of the progress.

I have one doubt though that I'm not sure how we could resolve and if it's necessary (how many times is EuiProgress used for fast processes and / or with long labels?).

Testing notes

VoiceOver (MacOS + Safari)

🔉 valueText={false}

Screen.Recording.2025-07-04.at.13.56.48.mov

🔉 valueText={true}

Screen.Recording.2025-07-04.at.13.57.48.mov

🔉 custom valueText

Screen.Recording.2025-07-04.at.13.58.57.mov

NVDA (Win + Edge)

🔉 valueText={false}

Screen.Recording.2025-07-04.at.13.46.14.mov

🔉 valueText={true}

Screen.Recording.2025-07-04.at.13.48.26.mov

🔉 custom valueText

Screen.Recording.2025-07-04.at.13.50.39.mov

JAWS (Win + Edge)

🔉 valueText={false}

Screen.Recording.2025-07-04.at.14.07.02.mov

🔉 valueText={true}

Screen.Recording.2025-07-04.at.14.06.01.mov

🔉 custom valueText

Screen.Recording.2025-07-04.at.14.04.50.mov

Btw the JAWS screenshots in the description are uploaded to https://private-user-images.githubusercontent.com/ and so when I click on them to see the full image, it slaps me with 404 😞 I can sorta read the preview though.

@mgadewoll
Copy link
Contributor Author

Btw the JAWS screenshots in the description are uploaded to https://private-user-images.githubusercontent.com/ and so when I click on them to see the full image, it slaps me with 404 😞 I can sorta read the preview though.

@weronikaolejniczak Thanks for mentioning it! Not sure why that's happening. I updated the links and I'm able to open them now, could you confirm?

@weronikaolejniczak
Copy link
Contributor

@mgadewoll I can open the images now, thanks for updating them, Lene! 💚

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

cc @mgadewoll

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

cc @mgadewoll

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.

Thanks for addressing all my concerns and suggestions, and adding some improvements yourself! This is a big a11y improvement IMO. Good job, Lene! 🟢

@mgadewoll
Copy link
Contributor Author

@weronikaolejniczak Thank you for the great and detailed review 👏

@mgadewoll mgadewoll merged commit da738fb into elastic:main Jul 4, 2025
5 checks passed
acstll added a commit to acstll/kibana that referenced this pull request Jul 10, 2025
The markup now includes screen reader-only output,
see elastic/eui#8839
acstll added a commit to elastic/kibana that referenced this pull request Jul 14, 2025
`104.1.0` ⏩ `105.0.0`

[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)

## Package updates

### `@elastic/eui`

#### [`v105.0.0`](https://github.com/elastic/eui/releases/v105.0.0)

- Added marked row styling via the classes `euiDataGridRow--marked` and
`euiTableRow--marked` for `EuiDataGrid` and `EuiBasicTable`
([#8834](elastic/eui#8834))
- Added component tokens:
([#8834](elastic/eui#8834))
  - `dataGridRowBackgroundMarked`
  - `dataGridRowBackgroundMarkedHover`
  - `dataGridRowBorderActive`
  - `dataGridRowBorderHover`
  - `dataGridRowBorderMarked`
  - `tableRowBackgroundMarked`
  - `tableRowBackgroundMarkedHover`
- Added `EuiFlyoutChild` and `EuiFlyoutSessionProvider`
([#8771](elastic/eui#8771))
- Added `setListOptionRefs` prop on `EuiComboBoxList`
([#8829](elastic/eui#8829))

**Breaking changes**

- Removed `iInCircle` icon (use `info` instead)
([#8841](elastic/eui#8841))
- Removed `questionInCircle` icon (use `question` instead)
([#8841](elastic/eui#8841))

**Accessibility**

- Improved the experience of `EuiProgress` by ensuring that determinate
updates are read out immediately to screen readers
([#8839](elastic/eui#8839))
- Fixed missing screen reader output for `EuiComboBox` with `options`
that have custom `id` attributes
([#8829](elastic/eui#8829))

### `@elastic/eui-theme-borealis`

####
[`v3.2.0`](https://github.com/elastic/eui/blob/main/packages/eui-theme-borealis/changelogs/CHANGELOG_2025.md#v320)

- Added component tokens:
([#8834](elastic/eui#8834))
  - `dataGridRowBackgroundMarked`
  - `dataGridRowBackgroundMarkedHover`
  - `dataGridRowBorderActive`
  - `dataGridRowBorderHover`
  - `dataGridRowBorderMarked`
  - `tableRowBackgroundMarked`
  - `tableRowBackgroundMarkedHover`

## Summary

- **Marked row styling** for `EuiDataGrid` and `EuiBasicTable`: new CSS
classes are available for consistent styling of marked rows (different
from selected), including hover and cell outline styles
(elastic/eui#8834)
- **New flyout component**: `EuiFlyoutChild` allows side-by-side
(grouped) flyout panels (elastic/eui#8771)
- **Accessibility fixes:**
- `EuiComboBox` now supports custom option `id`s
(elastic/eui#8829)
- Updates on `EuiProgress` are properly announced by screen readers
(elastic/eui#8839)
- **Icon updates** (breaking change): `iInCircle` and `questionInCircle`
icons have been renamed to `info` and `question` respectively
(elastic/eui#8841)

---------

Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: Lene Gadewoll <[email protected]>
Bluefinger pushed a commit to Bluefinger/kibana that referenced this pull request Jul 22, 2025
`104.1.0` ⏩ `105.0.0`

[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)

## Package updates

### `@elastic/eui`

#### [`v105.0.0`](https://github.com/elastic/eui/releases/v105.0.0)

- Added marked row styling via the classes `euiDataGridRow--marked` and
`euiTableRow--marked` for `EuiDataGrid` and `EuiBasicTable`
([elastic#8834](elastic/eui#8834))
- Added component tokens:
([elastic#8834](elastic/eui#8834))
  - `dataGridRowBackgroundMarked`
  - `dataGridRowBackgroundMarkedHover`
  - `dataGridRowBorderActive`
  - `dataGridRowBorderHover`
  - `dataGridRowBorderMarked`
  - `tableRowBackgroundMarked`
  - `tableRowBackgroundMarkedHover`
- Added `EuiFlyoutChild` and `EuiFlyoutSessionProvider`
([elastic#8771](elastic/eui#8771))
- Added `setListOptionRefs` prop on `EuiComboBoxList`
([elastic#8829](elastic/eui#8829))

**Breaking changes**

- Removed `iInCircle` icon (use `info` instead)
([elastic#8841](elastic/eui#8841))
- Removed `questionInCircle` icon (use `question` instead)
([elastic#8841](elastic/eui#8841))

**Accessibility**

- Improved the experience of `EuiProgress` by ensuring that determinate
updates are read out immediately to screen readers
([elastic#8839](elastic/eui#8839))
- Fixed missing screen reader output for `EuiComboBox` with `options`
that have custom `id` attributes
([elastic#8829](elastic/eui#8829))

### `@elastic/eui-theme-borealis`

####
[`v3.2.0`](https://github.com/elastic/eui/blob/main/packages/eui-theme-borealis/changelogs/CHANGELOG_2025.md#v320)

- Added component tokens:
([elastic#8834](elastic/eui#8834))
  - `dataGridRowBackgroundMarked`
  - `dataGridRowBackgroundMarkedHover`
  - `dataGridRowBorderActive`
  - `dataGridRowBorderHover`
  - `dataGridRowBorderMarked`
  - `tableRowBackgroundMarked`
  - `tableRowBackgroundMarkedHover`

## Summary

- **Marked row styling** for `EuiDataGrid` and `EuiBasicTable`: new CSS
classes are available for consistent styling of marked rows (different
from selected), including hover and cell outline styles
(elastic/eui#8834)
- **New flyout component**: `EuiFlyoutChild` allows side-by-side
(grouped) flyout panels (elastic/eui#8771)
- **Accessibility fixes:**
- `EuiComboBox` now supports custom option `id`s
(elastic/eui#8829)
- Updates on `EuiProgress` are properly announced by screen readers
(elastic/eui#8839)
- **Icon updates** (breaking change): `iInCircle` and `questionInCircle`
icons have been renamed to `info` and `question` respectively
(elastic/eui#8841)

---------

Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: Lene Gadewoll <[email protected]>
kertal pushed a commit to kertal/kibana that referenced this pull request Jul 25, 2025
`104.1.0` ⏩ `105.0.0`

[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)

## Package updates

### `@elastic/eui`

#### [`v105.0.0`](https://github.com/elastic/eui/releases/v105.0.0)

- Added marked row styling via the classes `euiDataGridRow--marked` and
`euiTableRow--marked` for `EuiDataGrid` and `EuiBasicTable`
([elastic#8834](elastic/eui#8834))
- Added component tokens:
([elastic#8834](elastic/eui#8834))
  - `dataGridRowBackgroundMarked`
  - `dataGridRowBackgroundMarkedHover`
  - `dataGridRowBorderActive`
  - `dataGridRowBorderHover`
  - `dataGridRowBorderMarked`
  - `tableRowBackgroundMarked`
  - `tableRowBackgroundMarkedHover`
- Added `EuiFlyoutChild` and `EuiFlyoutSessionProvider`
([elastic#8771](elastic/eui#8771))
- Added `setListOptionRefs` prop on `EuiComboBoxList`
([elastic#8829](elastic/eui#8829))

**Breaking changes**

- Removed `iInCircle` icon (use `info` instead)
([elastic#8841](elastic/eui#8841))
- Removed `questionInCircle` icon (use `question` instead)
([elastic#8841](elastic/eui#8841))

**Accessibility**

- Improved the experience of `EuiProgress` by ensuring that determinate
updates are read out immediately to screen readers
([elastic#8839](elastic/eui#8839))
- Fixed missing screen reader output for `EuiComboBox` with `options`
that have custom `id` attributes
([elastic#8829](elastic/eui#8829))

### `@elastic/eui-theme-borealis`

####
[`v3.2.0`](https://github.com/elastic/eui/blob/main/packages/eui-theme-borealis/changelogs/CHANGELOG_2025.md#v320)

- Added component tokens:
([elastic#8834](elastic/eui#8834))
  - `dataGridRowBackgroundMarked`
  - `dataGridRowBackgroundMarkedHover`
  - `dataGridRowBorderActive`
  - `dataGridRowBorderHover`
  - `dataGridRowBorderMarked`
  - `tableRowBackgroundMarked`
  - `tableRowBackgroundMarkedHover`

## Summary

- **Marked row styling** for `EuiDataGrid` and `EuiBasicTable`: new CSS
classes are available for consistent styling of marked rows (different
from selected), including hover and cell outline styles
(elastic/eui#8834)
- **New flyout component**: `EuiFlyoutChild` allows side-by-side
(grouped) flyout panels (elastic/eui#8771)
- **Accessibility fixes:**
- `EuiComboBox` now supports custom option `id`s
(elastic/eui#8829)
- Updates on `EuiProgress` are properly announced by screen readers
(elastic/eui#8839)
- **Icon updates** (breaking change): `iInCircle` and `questionInCircle`
icons have been renamed to `info` and `question` respectively
(elastic/eui#8841)

---------

Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: Lene Gadewoll <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[EuiProgress][A11y] Enable determinate status updates being read to screen readers

3 participants