-
Notifications
You must be signed in to change notification settings - Fork 860
[EuiLiveAnnouncer][A11y] Support live announcements on mount #8916
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
[EuiLiveAnnouncer][A11y] Support live announcements on mount #8916
Conversation
8ce548d to
41eee00
Compare
41eee00 to
e04e5a2
Compare
| import { EuiCallOut, EuiButton, EuiSpacer } from '@elastic/eui'; | ||
|
|
||
| export default () => { | ||
| const [isShown, setIsShown] = useState(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great thinking on making this false by default :D
tkajtoch
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code changes look great! I followed the QA instructions and tested with VoiceOver + Chrome on macOS and NVDA + Chrome on Windows. EuiLiveAnnouncer feels so much better! 🎉
💚 Build SucceededHistory
cc @mgadewoll |
💚 Build Succeeded
History
cc @mgadewoll |
- `@elastic/eui`: `v106.2.0` ⏩ `v106.3.0` - `@elastic/eui-theme-borealis`: `v3.3.0` ⏩ `v3.3.1` - `@elastic/eslint-plugin-eui`: `v2.2.1` ⏩ `v2.3.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` #### [`v106.3.0`](https://github.com/elastic/eui/releases/v106.3.0) - Added thumbUp and thumbDown icons ([#8937](elastic/eui#8937)) - Removed obsolete IE-specific CSS properties ([#8940](elastic/eui#8940)) - Updated `EuiComboBox` to allow multiline options by disabling virtualization (`rowHeight="auto"`) ([#8934](elastic/eui#8934)) **Bug fixes** - Fixed interactive content in header cells on `EuiDataGrid` not being correctly removed from the tab order ([#8938](elastic/eui#8938)) - Fixed an issue where the validity state of `EuiFieldNumber` did not update when the `isInvalid` prop value changed ([#8952](elastic/eui#8952)) - Reverted a font-size change for `xs` buttons back to `12px` ([#8930](elastic/eui#8930)) - Fixed unexpected results for the SCSS function `lineHeightFromBaseline` ([#8922](elastic/eui#8922)) - Fixed `euiDataGridRow--selected` not applying on `EuiDataGrid` whith `stripes={true}` ([#8925](elastic/eui#8925)) - Fixed `euiDataGridRow--marked` and `euiDataGridRow--selected` applying hover styling on `EuiDataGrid` when `stripes={true}` ([#8925](elastic/eui#8925)) **Accessibility** - Added a screen reader help text for entered interactive cells of `EuiDataGrid` to provide information about exiting cells ([#8938](elastic/eui#8938)) - Added a new beta `EuiLiveAnnouncer` component which supports `aria-live` announcements on mount ([#8916](elastic/eui#8916)) - Added `announceOnMount` prop on `EuiCallOut` to support announcing its content on mount ([#8916](elastic/eui#8916)) ### `@elastic/eui-theme-borealis` #### [`v3.3.1`](https://www.npmjs.com/package/@elastic/eui-theme-borealis/v/3.3.1) **Bug fixes** - Updated shared theme SCSS imports to ensure expected results for the SCSS function `lineHeightFromBaseline` ([#8922](elastic/eui#8922)) ### `@elastic/eslint-plugin-eui` #### [`v2.3.0`](https://www.npmjs.com/package/@elastic/eslint-plugin-eui/v/2.3.0) - Added `EuiFlyoutResizable` to `require-aria-label-for-modals` check ([#8946](elastic/eui#8946)) - Added new `no-unnamed-radio-group` rule. ([#8929](elastic/eui#8929)) - Fixed attributes comparison issue in the `consistent-is-invalid-props` rule. ([#8920](elastic/eui#8920))
- `@elastic/eui`: `v106.2.0` ⏩ `v106.3.0` - `@elastic/eui-theme-borealis`: `v3.3.0` ⏩ `v3.3.1` - `@elastic/eslint-plugin-eui`: `v2.2.1` ⏩ `v2.3.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` #### [`v106.3.0`](https://github.com/elastic/eui/releases/v106.3.0) - Added thumbUp and thumbDown icons ([elastic#8937](elastic/eui#8937)) - Removed obsolete IE-specific CSS properties ([elastic#8940](elastic/eui#8940)) - Updated `EuiComboBox` to allow multiline options by disabling virtualization (`rowHeight="auto"`) ([elastic#8934](elastic/eui#8934)) **Bug fixes** - Fixed interactive content in header cells on `EuiDataGrid` not being correctly removed from the tab order ([elastic#8938](elastic/eui#8938)) - Fixed an issue where the validity state of `EuiFieldNumber` did not update when the `isInvalid` prop value changed ([elastic#8952](elastic/eui#8952)) - Reverted a font-size change for `xs` buttons back to `12px` ([elastic#8930](elastic/eui#8930)) - Fixed unexpected results for the SCSS function `lineHeightFromBaseline` ([elastic#8922](elastic/eui#8922)) - Fixed `euiDataGridRow--selected` not applying on `EuiDataGrid` whith `stripes={true}` ([elastic#8925](elastic/eui#8925)) - Fixed `euiDataGridRow--marked` and `euiDataGridRow--selected` applying hover styling on `EuiDataGrid` when `stripes={true}` ([elastic#8925](elastic/eui#8925)) **Accessibility** - Added a screen reader help text for entered interactive cells of `EuiDataGrid` to provide information about exiting cells ([elastic#8938](elastic/eui#8938)) - Added a new beta `EuiLiveAnnouncer` component which supports `aria-live` announcements on mount ([elastic#8916](elastic/eui#8916)) - Added `announceOnMount` prop on `EuiCallOut` to support announcing its content on mount ([elastic#8916](elastic/eui#8916)) ### `@elastic/eui-theme-borealis` #### [`v3.3.1`](https://www.npmjs.com/package/@elastic/eui-theme-borealis/v/3.3.1) **Bug fixes** - Updated shared theme SCSS imports to ensure expected results for the SCSS function `lineHeightFromBaseline` ([elastic#8922](elastic/eui#8922)) ### `@elastic/eslint-plugin-eui` #### [`v2.3.0`](https://www.npmjs.com/package/@elastic/eslint-plugin-eui/v/2.3.0) - Added `EuiFlyoutResizable` to `require-aria-label-for-modals` check ([elastic#8946](elastic/eui#8946)) - Added new `no-unnamed-radio-group` rule. ([elastic#8929](elastic/eui#8929)) - Fixed attributes comparison issue in the `consistent-is-invalid-props` rule. ([elastic#8920](elastic/eui#8920))
- `@elastic/eui`: `v106.2.0` ⏩ `v106.3.0` - `@elastic/eui-theme-borealis`: `v3.3.0` ⏩ `v3.3.1` - `@elastic/eslint-plugin-eui`: `v2.2.1` ⏩ `v2.3.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` #### [`v106.3.0`](https://github.com/elastic/eui/releases/v106.3.0) - Added thumbUp and thumbDown icons ([elastic#8937](elastic/eui#8937)) - Removed obsolete IE-specific CSS properties ([elastic#8940](elastic/eui#8940)) - Updated `EuiComboBox` to allow multiline options by disabling virtualization (`rowHeight="auto"`) ([elastic#8934](elastic/eui#8934)) **Bug fixes** - Fixed interactive content in header cells on `EuiDataGrid` not being correctly removed from the tab order ([elastic#8938](elastic/eui#8938)) - Fixed an issue where the validity state of `EuiFieldNumber` did not update when the `isInvalid` prop value changed ([elastic#8952](elastic/eui#8952)) - Reverted a font-size change for `xs` buttons back to `12px` ([elastic#8930](elastic/eui#8930)) - Fixed unexpected results for the SCSS function `lineHeightFromBaseline` ([elastic#8922](elastic/eui#8922)) - Fixed `euiDataGridRow--selected` not applying on `EuiDataGrid` whith `stripes={true}` ([elastic#8925](elastic/eui#8925)) - Fixed `euiDataGridRow--marked` and `euiDataGridRow--selected` applying hover styling on `EuiDataGrid` when `stripes={true}` ([elastic#8925](elastic/eui#8925)) **Accessibility** - Added a screen reader help text for entered interactive cells of `EuiDataGrid` to provide information about exiting cells ([elastic#8938](elastic/eui#8938)) - Added a new beta `EuiLiveAnnouncer` component which supports `aria-live` announcements on mount ([elastic#8916](elastic/eui#8916)) - Added `announceOnMount` prop on `EuiCallOut` to support announcing its content on mount ([elastic#8916](elastic/eui#8916)) ### `@elastic/eui-theme-borealis` #### [`v3.3.1`](https://www.npmjs.com/package/@elastic/eui-theme-borealis/v/3.3.1) **Bug fixes** - Updated shared theme SCSS imports to ensure expected results for the SCSS function `lineHeightFromBaseline` ([elastic#8922](elastic/eui#8922)) ### `@elastic/eslint-plugin-eui` #### [`v2.3.0`](https://www.npmjs.com/package/@elastic/eslint-plugin-eui/v/2.3.0) - Added `EuiFlyoutResizable` to `require-aria-label-for-modals` check ([elastic#8946](elastic/eui#8946)) - Added new `no-unnamed-radio-group` rule. ([elastic#8929](elastic/eui#8929)) - Fixed attributes comparison issue in the `consistent-is-invalid-props` rule. ([elastic#8920](elastic/eui#8920))
- `@elastic/eui`: `v106.2.0` ⏩ `v106.3.0` - `@elastic/eui-theme-borealis`: `v3.3.0` ⏩ `v3.3.1` - `@elastic/eslint-plugin-eui`: `v2.2.1` ⏩ `v2.3.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` #### [`v106.3.0`](https://github.com/elastic/eui/releases/v106.3.0) - Added thumbUp and thumbDown icons ([elastic#8937](elastic/eui#8937)) - Removed obsolete IE-specific CSS properties ([elastic#8940](elastic/eui#8940)) - Updated `EuiComboBox` to allow multiline options by disabling virtualization (`rowHeight="auto"`) ([elastic#8934](elastic/eui#8934)) **Bug fixes** - Fixed interactive content in header cells on `EuiDataGrid` not being correctly removed from the tab order ([elastic#8938](elastic/eui#8938)) - Fixed an issue where the validity state of `EuiFieldNumber` did not update when the `isInvalid` prop value changed ([elastic#8952](elastic/eui#8952)) - Reverted a font-size change for `xs` buttons back to `12px` ([elastic#8930](elastic/eui#8930)) - Fixed unexpected results for the SCSS function `lineHeightFromBaseline` ([elastic#8922](elastic/eui#8922)) - Fixed `euiDataGridRow--selected` not applying on `EuiDataGrid` whith `stripes={true}` ([elastic#8925](elastic/eui#8925)) - Fixed `euiDataGridRow--marked` and `euiDataGridRow--selected` applying hover styling on `EuiDataGrid` when `stripes={true}` ([elastic#8925](elastic/eui#8925)) **Accessibility** - Added a screen reader help text for entered interactive cells of `EuiDataGrid` to provide information about exiting cells ([elastic#8938](elastic/eui#8938)) - Added a new beta `EuiLiveAnnouncer` component which supports `aria-live` announcements on mount ([elastic#8916](elastic/eui#8916)) - Added `announceOnMount` prop on `EuiCallOut` to support announcing its content on mount ([elastic#8916](elastic/eui#8916)) ### `@elastic/eui-theme-borealis` #### [`v3.3.1`](https://www.npmjs.com/package/@elastic/eui-theme-borealis/v/3.3.1) **Bug fixes** - Updated shared theme SCSS imports to ensure expected results for the SCSS function `lineHeightFromBaseline` ([elastic#8922](elastic/eui#8922)) ### `@elastic/eslint-plugin-eui` #### [`v2.3.0`](https://www.npmjs.com/package/@elastic/eslint-plugin-eui/v/2.3.0) - Added `EuiFlyoutResizable` to `require-aria-label-for-modals` check ([elastic#8946](elastic/eui#8946)) - Added new `no-unnamed-radio-group` rule. ([elastic#8929](elastic/eui#8929)) - Fixed attributes comparison issue in the `consistent-is-invalid-props` rule. ([elastic#8920](elastic/eui#8920))
Summary
closes #8821
This PR introduces a new component:
EuiLiveAnnouncer. This component aims to provide an alternative way (toEuiScreenReaderLive) of handling live region announcements.Information about the testing scope
It's not feasible for us to test all possible screen reader and browser combinations but we can determine a set that covers the majority of users. Based on the latest screen reader survey we can make some generic assumptions:
If we test the following combinations we can cover ~ 74% of usages:
The Problem(s)
The limitation of
aria-liveregions is that they have to be loaded and available in the DOM before content changes are being read out by screen readers. This means that the available componentEuiScreenReaderLivecurrently only reads content updates, but it does not read the content on mount.EuiScreenReaderLiverelies on two siblingaria-liveregions which receive content updates in turn. This pattern aims to ensure predictable output even if announcements happen in rapid succession or identical content is passed.Unfortunately this implementation showed flaws when testing. Especially the oscillating
aria-hiddenandaria-liveattributes (code) cause varying output behaviors across different screen reader and browser combinations. It leads to announcements being skipped at time or not being read at all in some testing scenarios.🚫 The current implementation results in no content being read at all in VoiceOver/Safari.
The proposed solution(s)
EuiLiveAnnounceraims to provide support for announcements on mount, e.g. when showing UI based on user interaction. AdditionallyEuiLiveAnnouncerproposes a different approach to handlingaria-liveannouncements to improve the output support and consistency across screen reader and browser combinations.Important
EuiLiveAnnounceris being added as standalone component next toEuiScreenReaderLiveto test it while being in Beta status. This way we can adjust and compare behaviors. If the component proves to behave better thanEuiScreenReaderLiveacross the board, the plan would be to replaceEuiScreenReaderLivewithEuiLiveAnnouncer.How it's done
EuiLiveAnnouncerutilizes a minimal timeout on mount of the component to set the passed content. This means initially the DOM element renders without content and is being updated shortly after with the expected content. This ensures the content is read as an update to the DOM element happened.Instead of using two sibling elements that alternate being updated with content,
EuiLiveAnnounceruses a single DOM element and utilizes React state to set content and trigger re-renders.Additionally it clears the content after a configurable timeout which ensures that duplicate content can be read as well as preventing duplicate content being available in the DOM for screen reader users to navigate.
Note
Clearing the content did not result in any issues when testing. A message that a screen reader started to read, was being read even after the content was cleared.
Component comparison
EuiLiveAnnouncerEuiScreenReaderLiveclearAfterMs)focusRegionOnTextChangeprop)Known limitations and issues
Generic
EuiLiveAnnouncerScreen.Recording.2025-07-28.at.10.47.27.mov
EuiScreenReaderLiveScreen.Recording.2025-07-28.at.10.40.38.mov
Screen.Recording.2025-07-28.at.10.44.27.mov
Why are we making this change?
The new component aims to provide a solution to a missing functionality (live announcements on mount) as well as providing a more consistent live region announcement experience.
Screenshots
Screen recordings
Screen.Recording.2025-07-24.at.19.49.59.mov
Screen.Recording.2025-07-24.at.19.53.54.mov
Screen.Recording.2025-07-28.at.10.22.16.mov
Screen.Recording.2025-07-28.at.10.27.01.mov
Screen.Recording.2025-07-24.at.19.57.25.mov
Screen.Recording.2025-07-24.at.19.58.00.mov
Screen.Recording.2025-07-24.at.20.00.48.mov
Screen.Recording.2025-07-24.at.20.01.45.mov
Impact to users
🟢 There are no updates needed by consumers.
QA
Test stories:
Added documentation:
EuiLiveAnnouncerin different testing scenarios (as mentioned above) and verify that:clearAfterMsis set which means there is no duplicate content in the DOM after the content being clearedEuiLiveAnnouncerwithEuiScreenReaderLiveEuiCallOutwithannounceOnMountis being read on mountEuiCallOutthat the screen reader only text added withannounceOnMountis being cleared to prevent duplicate DOM contentGeneral checklist
Browser QA
Checked in both light and dark modesChecked in both MacOS and Windows high contrast modesChecked in mobileDocs site QA
@defaultif default values are missing) and playground togglesChecked Code Sandbox works for any docs examplesCode quality checklist
Updated visual regression testsRelease checklist
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)Todo