Problem Statement
Accordions are a staple UI component, but they are frequently built in a way that excludes keyboard and screen-reader users. We need a reusable, dynamic accordion component in React that displays a list of collapsible panels.
When a user interacts with the accordion:
- They should be able to click on a panel header to expand it while collapsing other panels.
- The UI must react instantly and handle smooth height transitions when shifting between collapsed and expanded states.
- The component must support full keyboard control and broadcast its state semantically via ARIA attributes.
Requirements
Functional
- Dynamic Content: Accept an array of items, each containing a
title(ReactNode) and acontent(ReactNode). - Toggle Expansion: Clicking a header toggles that section between expanded and collapsed. Expanding one section should automatically collapse the currently expanded section (single-panel accordion).
- Keyboard Navigation:
- Focus should move between panel headers using the
Tabkey. - Pressing
SpaceorEnteron a focused header toggles its expansion state. - Pressing
Arrow Downmoves focus to the next panel header. - Pressing
Arrow Upmoves focus to the previous panel header. - Pressing
Homemoves focus to the first panel header. - Pressing
Endmoves focus to the last panel header.
- Focus should move between panel headers using the
- ARIA Semantic Attributes:
- The header trigger must be a
<button>or haverole="button". - Set
aria-expanded(true/false) on the header trigger representing its current state. - Link the header trigger to the content container using
aria-controlsmatching the panel content'sid. - Define
aria-labelledbyon the content container pointing to the header'sid. - Set
role="region"on the content container to indicate a landmarked section.
- The header trigger must be a
Non-Functional
- Ensure smooth visual transition of panel heights without layout jumps.
- Expose clean, strongly typed props in TypeScript.
- Strictly enforce focus boundaries so off-screen panel text is not focusable or interactive while collapsed.
Concepts Tested
- React state arrays and index selection logic.
- Focus management and keyboard accessibility (Event listener mapping).
- DOM manipulation using refs to control focus flow.
- CSS transition properties and
max-height/gridlayout styles.
