[EuiSelectable][EuiComboBox] Fix duplicated screen reader announcements of option name and checked state - #9850
Conversation
…uncement The checked state of a selectable list item is already conveyed natively via aria-checked/aria-selected, so the additional visually-hidden "Checked option." text caused screen readers (e.g. NVDA) to announce the state twice. Fixes elastic/kibana#216048 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…element A title attribute on the option <li> maps to the option's accessible description (HTML-AAM), which screen readers announce in addition to the accessible name - so the option name was read twice. Moving the title to the inner text element keeps the hover tooltip for truncated text without affecting the option's name/description computation. Part of elastic/kibana#216157 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR improves accessibility for option rows in EuiSelectable and EuiComboBox by eliminating duplicate screen reader announcements caused by redundant visually-hidden “checked” text and by title attributes being applied to the option container element.
Changes:
- Removed the screen-reader-only “Checked option.” text for checked selectable options (relies on native
aria-checked/aria-selectedinstead). - Moved truncation
titleattributes from the option element to the inner text element for both selectable and combo box options. - Widened
EuiListItemLayout’stextPropstyping to allow passing standard HTML attributes (e.g.title), and updated tests/snapshots/a11y assertions plus a changelog entry.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/eui/src/components/selectable/selectable_list/selectable_list_item.tsx | Removes redundant checked SR text; moves title to the inner text span via textProps. |
| packages/eui/src/components/selectable/selectable_list/selectable_list_item.test.tsx | Adds a regression test asserting title is not on the option element but on the text element. |
| packages/eui/src/components/selectable/selectable_list/snapshots/selectable_list.test.tsx.snap | Updates snapshots for title placement changes. |
| packages/eui/src/components/selectable/selectable_list/snapshots/selectable_list_item.test.tsx.snap | Updates snapshots to reflect removal of “Checked option.” SR-only text. |
| packages/eui/src/components/selectable/snapshots/selectable.test.tsx.snap | Updates snapshots for title placement changes in selectable render output. |
| packages/eui/src/components/list_item_layout/_list_item_layout.tsx | Widens textProps type to accept HTML attributes (enables title on text span). |
| packages/eui/src/components/filter_group/filter_group.a11y.tsx | Updates Cypress a11y assertion to reflect removal of “Checked option.” text. |
| packages/eui/src/components/combo_box/combo_box_options_list/combo_box_options_list.tsx | Moves truncation title off the option element and onto the inner text element. |
| packages/eui/src/components/combo_box/snapshots/combo_box.test.tsx.snap | Updates snapshots for combo box option title placement changes. |
| packages/eui/changelogs/upcoming/9850.md | Adds changelog entry documenting the accessibility improvements. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…the option element Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
acstll
left a comment
There was a problem hiding this comment.
Thanks you @alexwizp, code changes look good. I tested with Chrome/NVDA and it works as expected.
(I found sometimes there's a space with a dot after the option name e.g. Rhea . Checked foo bar that gets literally announced as "dot", but that's out of the scope of this PR)
Not approving yet because it's likely that the title change might cause a couple of tests in Kibana to break. Tests using selectors such as .euiSelectableListItem[title="${intervalTitle}"]. Ideally we deal with those before/during merging so upgrading after releasing is easier…
Kibana Regression Integration TestStatus: 💔 Kibana CI failed Please check Kibana CI logs for details. |
Co-authored-by: Arturo Castillo Delgado <arturo@arturu.com>
💚 Build Succeeded
History
|
💚 Build Succeeded
History
|
Summary
EuiSelectable/EuiComboBoxoptions. Two changes:EuiSelectableListItem.titleattribute from the option<li>element to its inner text element (EuiSelectableandEuiComboBox).aria-checked/aria-selectedon the option<li>, so screen readers (e.g. NVDA) announced the checked state twice — once from the ARIA attribute ("checked 1 of 4") and once from the extra hidden text ("Checked option.").titleattribute on the option<li>maps to the option's accessible description (per HTML-AAM), which screen readers announce in addition to the accessible name — so the option name was read twice.euiSelectableListItem.checkedOptionstate string forchecked="on"inselectable_list_item.tsx. The "Excluded option." (checked="off") and "Mixed (indeterminate) option." (checked="mixed") state texts are kept, as those states are not (or not reliably) distinguishable from the ARIA attributes alone. Keyboard instructions ("To uncheck/exclude this option, press Enter.") are unchanged.EuiSelectableListItemnow interceptstitleand renders it on the.euiSelectableListItem__textspan viatextProps;EuiComboBoxOptionsListdoes the same foreuiComboBoxOptionitems. The native hover tooltip for CSS-truncated text is preserved (it now triggers over the text rather than the whole row), but thetitleno longer participates in the option's accessible name/description computation. Follows up on [EuiToolTip] Replace all title attributes with EuiToolTip #9643, which narrowed when thetitleis set.Screen reader output for a checked option "System", before → after:
API Changes
euiSelectableListItem.checkedOptioni18n tokenaria-checked/aria-selectedtitleattribute<li>, so it no longer becomes the option's accessible descriptiontextPropsCommonProps & HTMLAttributes<HTMLElement>) in addition toCommonPropsScreenshots
N/A — no visual changes; only visually-hidden screen reader text and attribute placement are affected (see before/after announcement text above).
Impact Assessment
Note: Most PRs should be tested in Kibana to help gauge their Impact before merging.
[title=...]on the<li>will need to target the inner text element instead — e.g. snapshot tests ofEuiSelectable/EuiComboBox/filter popover options.Impact level: 🟢 Low
Release Readiness
Documentation:N/A — no API or docs changesFigma:N/AMigration guide:N/AAdoption plan (new features):N/A — bug fixQA instructions for reviewer
EuiSelectabledemo with checked options (e.g. the Selectable docs or anEuiSearchBarfield_value_selectionfilter popover).titleattribute).EuiComboBoxoptions — the option name is announced only once.allowExclusions, navigate to an excluded option — "Excluded option." is still announced.EuiSelectable/EuiComboBox— the native browser tooltip with the full text still appears.Checklist before marking Ready for Review
QA: Tested docs changesN/Atitleplacement, and updated Cypress a11y assertionsBreaking changes: AddedN/Abreaking changelabelReviewer checklist