Skip to content

[EuiPopover] Accessibility – add a11y-friendly aria-expanded and aria-controls attributes#9381

Merged
alexwizp merged 17 commits intoelastic:mainfrom
alexwizp:feb-13
Feb 18, 2026
Merged

[EuiPopover] Accessibility – add a11y-friendly aria-expanded and aria-controls attributes#9381
alexwizp merged 17 commits intoelastic:mainfrom
alexwizp:feb-13

Conversation

@alexwizp
Copy link
Copy Markdown
Contributor

@alexwizp alexwizp commented Feb 13, 2026

Summary

Improves EuiPopover accessibility by adding a more complete, screen reader–friendly ARIA relationship between the popover trigger and the popover content. In particular, the trigger now exposes:

  • aria-expanded to reflect whether the popover is currently open
  • aria-controls to reference the popover panel element when it is rendered
    These attributes help assistive technologies understand that the trigger controls a popup, and whether that popup is open or closed.

Why are we making this change?

Without aria-expanded and aria-controls, many screen readers have less context about:

  • whether activating the trigger opened anything, and
  • what element is being controlled by the trigger.

This change aligns EuiPopover with common WAI-ARIA authoring practices for popover/disclosure-style interactions.

Screenshots

image

Impact to users

There are no breaking changes in this PR. DOM snapshots of updated components may change.

QA

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)
    • If the changes unblock an issue in a different repo, smoke tested carefully (see Testing EUI features in Kibana ahead of time)
  • 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)

if (this.button && prevProps.isOpen !== this.props.isOpen) {
const toggleButton = this.getFocusableToggleButton();
if (toggleButton) {
const isButtonLike = () => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Initially, I wanted to add this for all triggers, but encountered issues with EuiRange(where trigger is Input) and EuiInputPopover. These attributes are not valid in those cases.

@alexwizp alexwizp marked this pull request as ready for review February 13, 2026 16:02
@alexwizp alexwizp requested a review from a team as a code owner February 13, 2026 16:02
@elastic elastic deleted a comment from elasticmachine Feb 13, 2026
@acstll acstll self-requested a review February 16, 2026 09:15
Copy link
Copy Markdown
Contributor

@acstll acstll left a comment

Choose a reason for hiding this comment

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

Thank you @alexwizp for putting this one up!

I have a question regarding the implementation, I would expect the attributes, especially aria-expanded, to be present on the initial render but they're only added after the open state changes — is this intentional?

While testing (NDVA and VoiceOver) aria-controls didn't make a noticeable difference. However in the WAI patterns I've checked, it's present (example). So I don't think it hurts to have it, but I wanted to ask you: would you consider only adding it when the popover is open/visible? According to MDN, that would still be correct:

The aria-controls only needs to be set when the popup is visible, but it is valid and easier to program to reference an element that is not visible.

Also, since the button is not strictly part of the component (the consumer provides it), do you think a case exists where the consumer would need to set/control these attributes themselves?

Finally, if you agree to adding the attributes to the button on initial render is correct, I would suggest the following structure for the tests:

  • describe: aria attributes on trigger button
    • test: aria-expanded=false is set on initial render
    • test: aria-expanded is toggled according the open state
    • test: aria-controls is set when the popover is open

alexwizp and others added 2 commits February 17, 2026 12:50
Co-authored-by: Arturo Castillo Delgado <arturo@arturu.com>
@alexwizp
Copy link
Copy Markdown
Contributor Author

@acstll Thank you for your review — I appreciate the thoughtful feedback and agree with your comments.

Regarding your question:

Also, since the button is not strictly part of the component (the consumer provides it), do you think a case exists where the consumer would need to set/control these attributes themselves?

At this point, I’m not convinced that we need to complicate the API. I’m struggling to identify a realistic use case where exposing that level of control would provide meaningful value to the consumer.

# Conflicts:
#	packages/eui/src/components/date_picker/auto_refresh/__snapshots__/auto_refresh.test.tsx.snap
#	packages/eui/src/components/date_picker/super_date_picker/quick_select_popover/__snapshots__/quick_select_popover.test.tsx.snap
@acstll
Copy link
Copy Markdown
Contributor

acstll commented Feb 17, 2026

@acstll Thank you for your review — I appreciate the thoughtful feedback and agree with your comments.

my pleasure

Regarding your question:

Also, since the button is not strictly part of the component (the consumer provides it), do you think a case exists where the consumer would need to set/control these attributes themselves?

At this point, I’m not convinced that we need to complicate the API. I’m struggling to identify a realistic use case where exposing that level of control would provide meaningful value to the consumer.

completely agree 👍


I left a comment regarding a unit test failing… and 2 more nits with wording.

alexwizp and others added 5 commits February 17, 2026 18:18
Co-authored-by: Arturo Castillo Delgado <arturo@arturu.com>
Co-authored-by: Arturo Castillo Delgado <arturo@arturu.com>
@elasticmachine
Copy link
Copy Markdown
Collaborator

💚 Build Succeeded

History

@elasticmachine
Copy link
Copy Markdown
Collaborator

💚 Build Succeeded

History

Copy link
Copy Markdown
Contributor

@acstll acstll left a comment

Choose a reason for hiding this comment

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

🟢 Thanks again for the contribution, and for addressing the feedback.

@alexwizp alexwizp merged commit 40f52e4 into elastic:main Feb 18, 2026
5 checks passed
acstll added a commit to acstll/kibana that referenced this pull request Feb 24, 2026
aria-expanded="false" from EuiPopover
related to elastic/eui#9381
acstll added a commit to acstll/kibana that referenced this pull request Feb 24, 2026
acstll added a commit to elastic/kibana that referenced this pull request Feb 25, 2026
## Dependency updates

- `@elastic/eui` - v113.0.0 ⏩ v113.1.0
- `@elastic/eui-theme-borealis` - v6.0.0 ⏩ v6.1.0

---

## Changes

| Commit | Change | Teams (Code Owner) |
| :--- | :--- | :--- |
| 18ef117 | Update snapshots, new Assistance color tokens
([#9383](elastic/eui#9383)) |
@elastic/kibana-security |
| 3fad87f | Update snapshots, new `aria-expanded` attribute added to
button triggers of `EuiPopover`
([#9381](elastic/eui#9381)) |
@elastic/appex-sharedux, @elastic/kibana-visualizations,
@elastic/kibana-data-discovery |
| cc9e096 | Update snapshots, remove
`aria-controls` now handled by `EuiPopover` directly
([#9381](elastic/eui#9381)) |
@elastic/kibana-security |

## Package updates

### `@elastic/eui`
[v113.1.0](https://github.com/elastic/eui/releases/tag/v113.1.0)

- Added `data-test-subj` attributes to `EuiFlyoutMenu` elements: back
button, history dropdown, and history items.
([#9400](elastic/eui#9400))
- Added new assistance tokens:
([#9383](elastic/eui#9383))
    - `euiTheme.colors.backgroundFilledAssistance`
    - `euiTheme.colors.backgroundLightAssistance`
    - `euiTheme.colors.backgroundBaseAssistance`
    - `euiTheme.components.buttons.backgroundAssistanceHover`,
    - `euiTheme.components.buttons.backgroundFilledAssistanceHover`
    - `euiTheme.colors.backgroundBaseInteractiveHoverAssistance`
    - `euiTheme.colors.borderStrongAssistance`
    - `euiTheme.colors.borderBaseAssistance`
    - `euiTheme.colors.textAssistance`
    - `euiTheme.colors.vis.euiColorVisAssistance`
    - `euiTheme.colors.severity.assistance`
    - `euiTheme.colors.vis.euiColorVis10`
    - `euiTheme.colors.vis.euiColorVis11`
    - `euiTheme.colors.vis.euiColorVisText10`
    - `euiTheme.colors.vis.euiColorVisText11`
- Updated purple color palette shades 30-60 to slightly lighter values
([#9383](elastic/eui#9383))

**Accessibility**

- Adds `aria-expanded` and `aria-controls` to the `EuiPopover` trigger
button to improve screen reader context
([#9381](elastic/eui#9381))

### `@elastic/eui-theme-borealis` v6.1.0

- Added new assistance tokens:
([#9383](elastic/eui#9383))
    - `euiTheme.colors.backgroundFilledAssistance`
    - `euiTheme.colors.backgroundLightAssistance`
    - `euiTheme.colors.backgroundBaseAssistance`
    - `euiTheme.components.buttons.backgroundAssistanceHover`,
    - `euiTheme.components.buttons.backgroundFilledAssistanceHover`
    - `euiTheme.colors.backgroundBaseInteractiveHoverAssistance`
    - `euiTheme.colors.borderStrongAssistance`
    - `euiTheme.colors.borderBaseAssistance`
    - `euiTheme.colors.textAssistance`
    - `euiTheme.colors.vis.euiColorVisAssistance`
    - `euiTheme.colors.severity.assistance`
    - `euiTheme.colors.vis.euiColorVis10`
    - `euiTheme.colors.vis.euiColorVis11`
    - `euiTheme.colors.vis.euiColorVisText10`
    - `euiTheme.colors.vis.euiColorVisText11`
- Updated purple color palette shades 30-60 to slightly lighter values
([#9383](elastic/eui#9383))
qn895 pushed a commit to qn895/kibana that referenced this pull request Mar 11, 2026
## Dependency updates

- `@elastic/eui` - v113.0.0 ⏩ v113.1.0
- `@elastic/eui-theme-borealis` - v6.0.0 ⏩ v6.1.0

---

## Changes

| Commit | Change | Teams (Code Owner) |
| :--- | :--- | :--- |
| 18ef117 | Update snapshots, new Assistance color tokens
([elastic#9383](elastic/eui#9383)) |
@elastic/kibana-security |
| 3fad87f | Update snapshots, new `aria-expanded` attribute added to
button triggers of `EuiPopover`
([elastic#9381](elastic/eui#9381)) |
@elastic/appex-sharedux, @elastic/kibana-visualizations,
@elastic/kibana-data-discovery |
| cc9e096 | Update snapshots, remove
`aria-controls` now handled by `EuiPopover` directly
([elastic#9381](elastic/eui#9381)) |
@elastic/kibana-security |

## Package updates

### `@elastic/eui`
[v113.1.0](https://github.com/elastic/eui/releases/tag/v113.1.0)

- Added `data-test-subj` attributes to `EuiFlyoutMenu` elements: back
button, history dropdown, and history items.
([elastic#9400](elastic/eui#9400))
- Added new assistance tokens:
([elastic#9383](elastic/eui#9383))
    - `euiTheme.colors.backgroundFilledAssistance`
    - `euiTheme.colors.backgroundLightAssistance`
    - `euiTheme.colors.backgroundBaseAssistance`
    - `euiTheme.components.buttons.backgroundAssistanceHover`,
    - `euiTheme.components.buttons.backgroundFilledAssistanceHover`
    - `euiTheme.colors.backgroundBaseInteractiveHoverAssistance`
    - `euiTheme.colors.borderStrongAssistance`
    - `euiTheme.colors.borderBaseAssistance`
    - `euiTheme.colors.textAssistance`
    - `euiTheme.colors.vis.euiColorVisAssistance`
    - `euiTheme.colors.severity.assistance`
    - `euiTheme.colors.vis.euiColorVis10`
    - `euiTheme.colors.vis.euiColorVis11`
    - `euiTheme.colors.vis.euiColorVisText10`
    - `euiTheme.colors.vis.euiColorVisText11`
- Updated purple color palette shades 30-60 to slightly lighter values
([elastic#9383](elastic/eui#9383))

**Accessibility**

- Adds `aria-expanded` and `aria-controls` to the `EuiPopover` trigger
button to improve screen reader context
([elastic#9381](elastic/eui#9381))

### `@elastic/eui-theme-borealis` v6.1.0

- Added new assistance tokens:
([elastic#9383](elastic/eui#9383))
    - `euiTheme.colors.backgroundFilledAssistance`
    - `euiTheme.colors.backgroundLightAssistance`
    - `euiTheme.colors.backgroundBaseAssistance`
    - `euiTheme.components.buttons.backgroundAssistanceHover`,
    - `euiTheme.components.buttons.backgroundFilledAssistanceHover`
    - `euiTheme.colors.backgroundBaseInteractiveHoverAssistance`
    - `euiTheme.colors.borderStrongAssistance`
    - `euiTheme.colors.borderBaseAssistance`
    - `euiTheme.colors.textAssistance`
    - `euiTheme.colors.vis.euiColorVisAssistance`
    - `euiTheme.colors.severity.assistance`
    - `euiTheme.colors.vis.euiColorVis10`
    - `euiTheme.colors.vis.euiColorVis11`
    - `euiTheme.colors.vis.euiColorVisText10`
    - `euiTheme.colors.vis.euiColorVisText11`
- Updated purple color palette shades 30-60 to slightly lighter values
([elastic#9383](elastic/eui#9383))
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.

3 participants