This project is a React + TypeScript implementation of an accessible accordion component.
The solution focuses on:
- a reusable, typed component API
- accessibility-first behavior and semantics
- design token usage through CSS custom properties
- required test coverage
- React 19
- TypeScript
- Vite
- Vitest + React Testing Library
- ESLint + Prettier
- MUI
npm install
npm run devOpen the app in your browser from the local URL printed by Vite.
npm run dev- start development servernpm run build- build production bundlenpm run test- run unit/integration testsnpm run lint- run ESLintnpm run typecheck- run TypeScript checks without emitnpm run check- run typecheck, lint, and formatting check
Accordion accepts:
panels: AccordionPanel[](required)shouldAllowMultipleExpanded?: boolean(defaults totrue)
AccordionPanel shape:
id: string- stable identifier for keys/aria linkagetitle: string- trigger labelcontent: ReactNode- region content
Behavior:
- In multi-expand mode, multiple panels can remain open.
- In single-expand mode, opening one panel closes the previously open panel.
- Clicking an expanded panel toggles it closed.
The component uses native button semantics and explicit ARIA relationships:
- trigger button exposes
aria-expandedandaria-controls - content region uses
role="region"andaria-labelledby
Tokens live in src/design-system/tokens.ts and are mapped to CSS variables in src/design-system/theme.ts.
- centralized values for color, spacing, typography, radius, and motion
- component styling through semantic variables
Tests in src/components/Accordion/Accordion.test.tsx cover:
- initial collapsed render
- expand/collapse interactions
- multi-expand and single-expand behavior
- mode-switch reset behavior
- ARIA linkage integrity for controls and regions
Run:
npm run testsrc/
components/
Accordion/
design-system/
test/
-
The accordion is implemented with MUI primitives (
Accordion,AccordionSummary,AccordionDetails) -
Design tokens remain the source of truth for visual decisions through CSS custom properties.
-
I opted for a small, easy-to-demo project to meet the challenge requirements. In a production environment, I would typically house the design system in its own repository/package and manage it as a shared dependency (standalone package or Git submodule) so it can be consumed consistently across multiple applications