Skip to content

[EuiSelectable][A11y] Search input is not read out by screen readers#9223

Merged
mgadewoll merged 15 commits intoelastic:mainfrom
jorgeoliveira117:9161-euiselectable-a11y-search-input-is-not-read-out
Dec 1, 2025
Merged

[EuiSelectable][A11y] Search input is not read out by screen readers#9223
mgadewoll merged 15 commits intoelastic:mainfrom
jorgeoliveira117:9161-euiselectable-a11y-search-input-is-not-read-out

Conversation

@jorgeoliveira117
Copy link
Copy Markdown
Contributor

@jorgeoliveira117 jorgeoliveira117 commented Nov 18, 2025

Closes #9161

Summary

Updates focus behavior in EuiSelectable and ARIA attributes to match best practices. When focusing the search input, the active option remains visually focused, and aria-activedescendant is only added when an option is active.

Why are we making this change?

  • To preserve focus: Moving focus between the search input and the item list should keep the active option visually focused, improving keyboard navigation.

  • ARIA compliance: aria-activedescendant should only be present when there is an active descendant. An empty string is invalid.

Screenshots

Before:
When we open the popover/dialog and focus inside the Selectable component, the first item on the list is also focused

Before.mp4

After:
When we focus inside the Selectable component, now the first item isn't focused, only the search input

After.mp4

Impact to users

🟢 No breaking changes. No code updates are required on consumer side.

ℹ️ This fix has been run in Kibana CI and required test changes have been prepared here.

✨ User value

  • Better keyboard navigation as active option remains visible when focusing the search input
  • Improved accessibility as ARIA attributes follow best practices
  • More consistent UX when switching between search and list

QA

General checklist

  • Browser QA
    • 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
  • Code quality checklist
  • Release checklist

@jorgeoliveira117 jorgeoliveira117 marked this pull request as ready for review November 20, 2025 11:26
@jorgeoliveira117 jorgeoliveira117 requested a review from a team as a code owner November 20, 2025 11:26
@mgadewoll mgadewoll self-requested a review November 20, 2025 15:25
Copy link
Copy Markdown
Contributor

@mgadewoll mgadewoll 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 picking up this A11y fix!
I left a couple small comments for improvements, but in general the proposed update works as expected (tested in Jaws, NVDA and VoiceOver). 🎉

⚠️ Let's make sure to run the changes in Kibana CI and wait for the results to understand what might break and if there is anything else we might need to address.

@mgadewoll
Copy link
Copy Markdown
Contributor

ℹ️ @jorgeoliveira117 I merged main into your branch to have it updated before merging.
I also confirmed that the latest run of these changes on Kibana CI looked clean 👍

Copy link
Copy Markdown
Contributor

@mgadewoll mgadewoll 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 work as expected and fix the A11y issue.
Thank you for contributing! 🎉

@elasticmachine
Copy link
Copy Markdown
Collaborator

💚 Build Succeeded

History

@elasticmachine
Copy link
Copy Markdown
Collaborator

💚 Build Succeeded

History

@mgadewoll mgadewoll merged commit 5dcdde8 into elastic:main Dec 1, 2025
7 checks passed
mgadewoll added a commit to elastic/kibana that referenced this pull request Dec 8, 2025
## Dependency updates

- `@elastic/eui`: `v109.2.0` ⏩ `v110.0.0`

---

## Changes

- Updates usages of the `message` prop on `EuiInMemoryTable` to
`noItemsMessage`
- Updates usages of `EuiSearchBar`'s `onChange` prop to check for the
`query` argument, as it may be `null` now
- Removes obsolete `color` props on implementations of `EuiPageTemplate`
and `EuiPageTemplate.Header` (`color` prop wasn't applied before either)

## Package updates

### `@elastic/eui` v110.0.0

- Updated `EuiSuperDatePicker` to expose plain text `utcOffset` and
`timeZoneName` in `timeZoneDisplayProps.customRender` render function
([#9245](elastic/eui#9245))
- Updated `EuiHeaderLogo` to add a hover style
([#9240](elastic/eui#9240))
- Made `EuiQuickSelectPanel` available for importing from the
`@elastic/eui` package
([#9239](elastic/eui#9239))
- Updated `EuiAvatar` to support Emoji Sequence ("advanced") in the
`initials` prop ([#9227](elastic/eui#9227))
- Added `color` prop on `EuiPageHeader` to support `transparent`
(default) and `plain` backgrounds.
([#9220](elastic/eui#9220))
- Added `color` prop on `EuiPage` to support `transparent` (default) and
`plain` backgrounds. ([#9220](elastic/eui#9220))
- Updated `EuiPageTemplate` to ensure `panelled=true` renders a
`EuiPageHeader` with a plain background by default
([#9220](elastic/eui#9220))
- Removed the default background style on `EuiPageTemplate`'s outer
wrapper ([#9220](elastic/eui#9220))

**Bug fixes**

- Fixed icon size in `EuiSuperDatePicker`'s time window buttons when
`compressed={true}` ([#9245](elastic/eui#9245))
- Fixed `EuiIcon` visibility issue with `logoElastic` when `color` is
set to `text` or `ghost` in light mode
([#9247](elastic/eui#9247))
- Fixed `EuiInMemoryTable` support for controlled search for plain text
(when `searchFormat="text"`) by properly handling `search.query` and
`search.defaulQuery` ([#9142](elastic/eui#9142))

**Breaking changes**

- Removed deprecated `message` prop from `EuiInMemoryTable`, use
`noItemsMessage` instead
([#9234](elastic/eui#9234))

**Accessibility**

- Improved the accessibility of input fields in the popover of
`EuiSuperDatePicker` by properly labeling them
([#9239](elastic/eui#9239))
- Improved the accessibility of `EuiSelectable` by removing empty
`aria-activedescendant` attribute when no option is active to ensure the
search input is perceivable by screen readers
([#9223](elastic/eui#9223))

---------

Co-authored-by: Weronika Olejniczak <weronika.olejniczak@elastic.co>
Co-authored-by: Jorge Oliveira <jorge.oliveira@elastic.co>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
JordanSh pushed a commit to JordanSh/kibana that referenced this pull request Dec 9, 2025
## Dependency updates

- `@elastic/eui`: `v109.2.0` ⏩ `v110.0.0`

---

## Changes

- Updates usages of the `message` prop on `EuiInMemoryTable` to
`noItemsMessage`
- Updates usages of `EuiSearchBar`'s `onChange` prop to check for the
`query` argument, as it may be `null` now
- Removes obsolete `color` props on implementations of `EuiPageTemplate`
and `EuiPageTemplate.Header` (`color` prop wasn't applied before either)

## Package updates

### `@elastic/eui` v110.0.0

- Updated `EuiSuperDatePicker` to expose plain text `utcOffset` and
`timeZoneName` in `timeZoneDisplayProps.customRender` render function
([elastic#9245](elastic/eui#9245))
- Updated `EuiHeaderLogo` to add a hover style
([elastic#9240](elastic/eui#9240))
- Made `EuiQuickSelectPanel` available for importing from the
`@elastic/eui` package
([elastic#9239](elastic/eui#9239))
- Updated `EuiAvatar` to support Emoji Sequence ("advanced") in the
`initials` prop ([elastic#9227](elastic/eui#9227))
- Added `color` prop on `EuiPageHeader` to support `transparent`
(default) and `plain` backgrounds.
([elastic#9220](elastic/eui#9220))
- Added `color` prop on `EuiPage` to support `transparent` (default) and
`plain` backgrounds. ([elastic#9220](elastic/eui#9220))
- Updated `EuiPageTemplate` to ensure `panelled=true` renders a
`EuiPageHeader` with a plain background by default
([elastic#9220](elastic/eui#9220))
- Removed the default background style on `EuiPageTemplate`'s outer
wrapper ([elastic#9220](elastic/eui#9220))

**Bug fixes**

- Fixed icon size in `EuiSuperDatePicker`'s time window buttons when
`compressed={true}` ([elastic#9245](elastic/eui#9245))
- Fixed `EuiIcon` visibility issue with `logoElastic` when `color` is
set to `text` or `ghost` in light mode
([elastic#9247](elastic/eui#9247))
- Fixed `EuiInMemoryTable` support for controlled search for plain text
(when `searchFormat="text"`) by properly handling `search.query` and
`search.defaulQuery` ([elastic#9142](elastic/eui#9142))

**Breaking changes**

- Removed deprecated `message` prop from `EuiInMemoryTable`, use
`noItemsMessage` instead
([elastic#9234](elastic/eui#9234))

**Accessibility**

- Improved the accessibility of input fields in the popover of
`EuiSuperDatePicker` by properly labeling them
([elastic#9239](elastic/eui#9239))
- Improved the accessibility of `EuiSelectable` by removing empty
`aria-activedescendant` attribute when no option is active to ensure the
search input is perceivable by screen readers
([elastic#9223](elastic/eui#9223))

---------

Co-authored-by: Weronika Olejniczak <weronika.olejniczak@elastic.co>
Co-authored-by: Jorge Oliveira <jorge.oliveira@elastic.co>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
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.

[EuiSelectable][A11y] Search input is not read out by screen readers

3 participants