mui / mui/base-ui

[dialog] Rationale for `aria-expanded` on `Dialog.Trigger` (modal dialogs)

Open
#5,190 2 comments 0 reactions 0 assignees View on GitHub
component: dialog
Dominant language
TypeScript
Stars
10.9k
Forks
543
Avg merge
1d 20h
Merged PRs (30d)
101

Description

## Summary

`Dialog.Trigger` renders both `aria-haspopup="dialog"` and `aria-expanded` (reflecting open state). I'd like to understand the reasoning behind including `aria-expanded` on a modal dialog trigger, and whether it's something the team has deliberately considered vs. inherited from the shared trigger primitive.

## Context

This came out of an accessibility audit. The finding was:

> `aria-expanded` on the trigger button causes a misleading "collapsed" announcement. The trigger has `aria-expanded="false"`, which causes NVDA to announce something like "Open dialog, button, collapsed, opens dialog" — a confusing combination. `aria-expanded` is intended for widgets that expand and collapse inline content such as accordions and dropdowns. Opening a dialog is not inline content expansion. `aria-haspopup="dialog"` alone is the correct and sufficient attribute for a dialog trigger, and `aria-expanded` should be removed.

While a modal is open, focus is trapped inside it and the trigger is inert/unreachable, so `aria-expanded="true"` is effectively never announced in context. The only states a user actually encounters are `aria-expanded="false"` on initial render and again on close — i.e. the "collapsed" announcement, which is the confusing one.

So the attribute seems to only ever surface in the situation where it reads as noise, at least for the modal case. For **non-modal** popups (where the trigger stays in the tab order alongside the open content) `aria-expanded` clearly still makes sense.

## Questions

1. Is `aria-expanded` on `Dialog.Trigger` a deliberate choice, or a consequence of `Dialog` sharing a trigger primitive with `Popover` / `Menu` / `Select` etc.?
2. Has the modal vs. non-modal distinction come up in this context before?
3. Would you consider dropping `aria-expanded` for modal dialog triggers (or making it conditional on modality), or is there a rationale for keeping it that the audit finding overlooks?

Happy to open a PR if there's an agreed direction. Mostly want to understand the intent before we override it downstream.

Contributor guide

Open the contributing guide

Research direction

Start by tracing Dialog.Trigger and the shared trigger primitive used by Popover, Menu, and Select, then compare how modal and non-modal triggers expose ARIA state. Review the accessibility audit behavior with NVDA and determine whether modal dialog triggers should omit aria-expanded; done means the team has an agreed direction and any resulting behavior is covered by the relevant component tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
accessibility, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.