[accordion] Automatically set ARIA attributes#48559
Conversation
Deploy previewBundle size
Check out the code infra dashboard for more information about this PR. |
0afbcc2 to
99369fb
Compare
siriwatknp
left a comment
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
maybe memoize this so it's not computed on every render
| slotProps: | ||
| accordionContext === undefined | ||
| ? slotProps | ||
| : { | ||
| ...slotProps, | ||
| root: rootSlotPropsWithRelationship, | ||
| }, |
There was a problem hiding this comment.
maybe memoize this value so we don't compute {...slotProps, root: ... } on every render if the context is true
There was a problem hiding this comment.
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: {...} }}
| ## 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. |
There was a problem hiding this comment.
Maybe keep the section and also mention that we are computing the ids and aria-controls automatically but they can be overriden by props?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
Preview: https://deploy-preview-48559--material-ui.netlify.app/material-ui/react-accordion/
Also polished all the docs and demos, in particular added
Usage guidelineswith updated accessibility recommendations. The only previous recommendation was to add explicit ids and aria-controls which is no longer necessary.Closes #48305