Skip to content

[accordion] Automatically set ARIA attributes#48559

Open
mj12albert wants to merge 4 commits into
mui:masterfrom
mj12albert:accordion-auto-aria-attributes
Open

[accordion] Automatically set ARIA attributes#48559
mj12albert wants to merge 4 commits into
mui:masterfrom
mj12albert:accordion-auto-aria-attributes

Conversation

@mj12albert
Copy link
Copy Markdown
Member

@mj12albert mj12albert commented May 20, 2026

Preview: https://deploy-preview-48559--material-ui.netlify.app/material-ui/react-accordion/

Also polished all the docs and demos, in particular added Usage guidelines with updated accessibility recommendations. The only previous recommendation was to add explicit ids and aria-controls which is no longer necessary.

Closes #48305

@mj12albert mj12albert changed the title [accordion [accordion] Automatically set ARIA attributes May 20, 2026
@mj12albert mj12albert added accessibility a11y scope: accordion Changes related to the accordion. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. labels May 20, 2026
@code-infra-dashboard
Copy link
Copy Markdown

code-infra-dashboard Bot commented May 20, 2026

Deploy preview

Bundle size

Bundle Parsed size Gzip size
@mui/material 🔺+527B(+0.10%) 🔺+298B(+0.20%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@mj12albert mj12albert force-pushed the accordion-auto-aria-attributes branch from 0afbcc2 to 99369fb Compare May 21, 2026 00:07
@mj12albert mj12albert marked this pull request as ready for review May 21, 2026 00:22
@zannager zannager requested a review from Janpot May 21, 2026 14:13
@mj12albert mj12albert requested review from silviuaavram and siriwatknp and removed request for Janpot May 21, 2026 19:01
Copy link
Copy Markdown
Member

@siriwatknp siriwatknp left a comment

Choose a reason for hiding this comment

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

Quick question, which pattern is the doc update following?

@mj12albert
Copy link
Copy Markdown
Member Author

Quick question, which pattern is the doc update following?

You mean an aria pattern or reorganizing the structure of the sections and such?

hasGeneratedRegionId &&
(isRegionAlwaysMounted || (isDefaultCollapseTransition && expanded) || isRegionMounted);

const regionSlotProps = mergeSlotProps(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe memoize this so it's not computed on every render

Comment on lines +162 to +168
slotProps:
accordionContext === undefined
? slotProps
: {
...slotProps,
root: rootSlotPropsWithRelationship,
},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe memoize this value so we don't compute {...slotProps, root: ... } on every render if the context is true

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This doesn't help much because useSlot runs on every render anyway, and also doesn't help the common case of inline object slot props: slotProps={{ region: {...} }}

Comment on lines -119 to -122
## Accessibility

The [WAI-ARIA guidelines for accordions](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/) recommend setting an `id` and `aria-controls`, which in this case would apply to the Accordion Summary component.
The Accordion component then derives the necessary `aria-labelledby` and `id` from its content.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe keep the section and also mention that we are computing the ids and aria-controls automatically but they can be overriden by props?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The ARIA pattern is already linked via the "Chip" at the top, and since users generally don't need to do anything about ids anymore, there's not a lot of value in mentioning this as it's just describing an implementation detail/re-stating something from the APG

Also aria-controls isn't useful anyway as it historically has bad support and JAWSs ignores it by default

const summaryId = useId(summaryIdProp);
const regionId = useId(summaryAriaControlsProp);
const hasSummaryAriaControls = summaryAriaControlsProp != null;
const [isRegionMounted, setIsRegionMounted] = React.useState(false);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it an option to always mount the region node, but instead hide its content? Such that aria-controls always resolves, but we don't add an extra render to track the mount.

It could make sense to add a benchmark test like https://github.com/mui/base-ui-charts/tree/master/test/performance first to verify we're not adding extra renders.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sadly no, because the existing structure is:

<TransitionSlot {...transitionProps}>
  <RegionSlot {...regionProps}>{children}</RegionSlot>
</TransitionSlot>

always mounting the region would affect transitions

But yeah it's needed exactly to avoid orphaned aria-controls in cases like slotProps.transition={{ unmountOnExit: true }} or mountOnEnter: true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accessibility a11y scope: accordion Changes related to the accordion. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[accordion] Use context to remove need for manual id assigments

4 participants